In Oracle-Funktionen und -Triggern hole ich mir den aktuellen Benutzer meistens über folgende Logik:
coalesce( sys_context('apex$session', 'app_user') , sys_context('userenv', 'os_user') , sys_context('userenv', 'session_user') );
Der Vorteil davon ist, dass das ganze sowohl mit APEX als auch unabhängig davon funktioniert.
Wofür? Einsatz in Triggern
In Tabellen werden häufig Audit-Spalten verwendet, die über Trigger gefüllt werden. Außer dem Zeitpunkt wird dabei auch gespeichert, wer den Datensatz erstellt bzw. geändert hat.
Dabei hat es sind bewährt, den Benutzernamen zu speichern (und besser nicht die Benutzer-ID). Aber welcher Benutzer soll verwendet werden? APEX-, Betriebssystem- oder den Datenbank-Benutzer? Und wie ermittle ich diese am performantesten in Oracle? Hier meine Empfehlungen:
APEX-Benutzer
sys_context('apex$session', 'app_user')
Das funktionieren zwar auch mit den Varianten APEX_APPLICATION.g_user und v(‚APP_USER‘) in PL/SQL, diese sind allerdings weniger performant. (Die letzte ist übrigens am langsamsten, wie Jeff Kemp beschrieben hat.) Die Mindestvoraussetzung ist allerdings APEX 5.x, da erst ab dieser Version der Benutzer im sys_context enthalten ist.
Betriebssystem-Benutzer
sys_context('userenv', 'os_user')
Dieser sys_context gibt den am Betriebssystem angemeldeten Benutzer zurück. Also z.B. acme\johndoe, wenn der Benutzer an einer Domäne angemeldet ist.
Datenbank-Benutzer
sys_context('userenv', 'session_user')
Hier wird Datenbank-User der aktuellen DB-Session zurück gegeben.
Mit der Function coalesce() wird immer der erste Wert zurück gegeben, der NOT NULL ist. Am besten kapselt man das ganze in einer (Package-)Function.
function get_user return varchar2 is begin return coalesce( sys_context('apex$session', 'app_user') , sys_context('userenv', 'os_user') , sys_context('userenv', 'session_user') ); end get_user;
Damit ist es für Trigger, SQL-Abfragen usw. wiederverwendbar.