SYS_CONTEXT不僅能夠返回USERENV數據——它還能返回應用程序定義的數據值。應用程序上下文包括一組可以被SYS_CONTEXT返回的名稱(屬性)和匹配數據(值)。例如,如果一個人事應用要返回用戶的部門號,可以在應用程序中加入下面這行代碼:
v_dept := SYS_CONTEXT('HR_CONTEXT', 'DEPT');
Oracle 9i中推出的After Logon數據庫觸發器能夠方便地初始化應用程序上下文中的屬性。用戶成功登錄Oracle後,觸發器啟動,在指定的數據包中執行一個存儲過程查詢數據,並通過DBMS_SESSION.SET_CONTEXT過程把它放到上下文中。
使用這種方法有以下幾個好處:
·它的性能更強。應用程序上下文數據保存在SGA中,訪問它可以避免應用程序查詢數據時重復讀取磁盤。
·它更加安全。它使用一個與上下文有關的單獨PL/SQL代碼對象,通常是一個數據包來改變或清除上下文。After Logon觸發器正是執行的這個數據包。
·它相當靈活。你可以建立任何你需要的上下文,每個上下文中可包含無限數量的屬性-值對。
列表A說明了一個叫做HR_CONTEXT_PKG的PL/SQL數據包。它查詢當前用戶會話應與哪個部門有關,從而初始化HR_CONTEXT上下文。
然後你可以用下面的CREATE CONTEXT語句建立HR_CONTEXT命名空間,並把它與數據包相關聯。
CREATE CONTEXT hr_context
USING HR.HR_CONTEXT_PKG;
下面的代碼說明了一個登錄觸發器,它在用戶登錄時調用安全數據包為用戶初始化上下文。如果定位正確的部門出現錯誤,觸發器將通過一個EXCEPTION(異常)處理它。否則,沒有部門設置的用戶將無法登錄。
CREATE OR REPLACE TRIGGER DBT_LOGON
AFTER LOGON
ON DATABASE
BEGIN
HR.HR_CONTEXT_PKG.INITIALIZE_HR_CONTEXT;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
/
這樣,現在任何應用程序都能夠找出當前用戶與哪個部門相關聯,而不必進行多次邏輯讀取,從一個表中查詢它。例如:
SELECT SYS_CONTEXT('HR_CONTEXT','DEPT') FROM DUAL;
這行代碼將返回當前用戶的部門ID。