2009-12-10 14 views
12

Lo scopo è inviare informazioni aggiuntive a trigger come l'ID utente corrente da un'applicazione Web. Poiché viene utilizzato un pool di connessioni e viene utilizzato lo stesso ID utente per tutte le connessioni, come faccio a passare l'ID utente Web originale per l'attivazione? Questo ho bisogno di implementare senza toccare il codice dell'applicazione. È un'applicazione basata su Java.Come inviare parametri arbitrari al trigger Oracle?

John

risposta

1

È possibile utilizzare un pacchetto per tenere traccia degli utenti web:

create package web_user_pkg is 

    procedure set_username (p_username varchar2); 

    function username return varchar2; 

end; 

create package body web_user_pkg is 

    g_username varchar2(30); 

    procedure set_username (p_username varchar2) 
    is 
    begin 
     g_username := p_username; 
    end; 

    function username return varchar2 is 
    begin 
     return g_username; 
    end; 

end; 

Nella pagina web chiamata web_user_pkg.set_username con ID dell'utente corrente prima di eseguire qualsiasi DML o di altre chiamate di pacchetti .

Nel trigger utilizzare web_user_pkg.username per ottenere il nome utente web.

+0

Sembra essere una buona soluzione. Questa variabile del pacchetto è condivisa tra le altre connessioni? –

+0

No, è univoco per la connessione. Il pool di connessioni sarebbe inutilizzabile se diversi utenti finali condividessero lo stesso stato del database! –

+1

Giusto per chiarire, se ci sono 10 sessioni di database, allora ci sono un massimo di 10 stati di database simultanei anche se si hanno 50 utenti finali dell'applicazione. Il punto di un pool di connessioni è la condivisione di quelle sessioni di database. L'applicazione prenderebbe una connessione/sessione per la durata di una transazione. Non necessariamente usa la stessa connessione per una transazione successiva dallo stesso utente finale dell'applicazione. –

15

È possibile utilizzare la variabile di sessione client_identifier per passare un utente dell'applicazione a un trigger.

Set dopo la connessione al database in questo modo:

CALL dbms_session.set_identifier('<<username>>'); 

e recuperare dentro il grilletto:

SELECT sys_context('USERENV','CLIENT_IDENTIFIER') INTO username FROM DUAL; 

Maggiori informazioni si possono trovare nel Oracle docs

+0

+1 Questo sembra essere il modo "giusto" per farlo! –

+0

Funziona se hai solo bisogno di passare una di una manciata di attributi relativamente comuni al trigger. L'approccio di Vincent all'utilizzo dei contesti, tuttavia, consente il passaggio di parametri arbitrari. –

+4

Grazie, ho aiutato molto quando ero bloccato! Voglio solo menzionare, l'uso della parola "USERNAME" in maiuscolo nella prima riga di codice è un po 'confuso. Sembra che sia inteso per essere preso alla lettera, ma in realtà, è un sostituto dell'ID utente dell'utente dell'app connesso che si desidera inviare al trigger. Anche se la seconda riga di codice è pensata per essere letterale, supponendo che si desideri che "nome utente" sia la variabile che contiene l'ID utente dell'app utente connesso. –

8

si potrebbe usare Oracle Contexts:

SQL> CREATE OR REPLACE PACKAGE test_pkg AS 
    2  PROCEDURE set_context(p_attribute VARCHAR2, p_value VARCHAR2); 
    3 END test_pkg; 
    4/

Package created 
SQL> CREATE OR REPLACE PACKAGE BODY test_pkg AS 
    2  PROCEDURE set_context(p_attribute VARCHAR2, p_value VARCHAR2) IS 
    3  BEGIN 
    4  dbms_session.set_context('test_ctx', p_attribute, p_value); 
    5  END; 
    6 END test_pkg; 
    7/

Package body created 

SQL> create context test_ctx using test_pkg; 

Context created 

SQL> exec test_pkg.set_context ('user_id', 'Vincent'); 

PL/SQL procedure successfully completed 

SQL> select sys_context('test_ctx', 'user_id') from dual; 

SYS_CONTEXT('TEST_CTX','USER_I 
-------------------------------------------------------------------------------- 
Vincent 
Problemi correlati