我會使用上下文而不是傳遞額外的參數到每個存儲過程調用。上下文是存儲任意會話級別狀態數據的便利場所,存儲過程可以全部引用該數據。
例如,我可以爲我的應用程序創建一個上下文MYAPP_CTX
並創建一個簡單的包,讓我可以在上下文中設置任何我想要的值。
SQL> create context myapp_ctx using ctx_pkg;
Context created.
SQL> create package ctx_pkg
2 as
3 procedure set_value(p_key in varchar2, p_value in varchar2);
4 end;
5/
Package created.
SQL> create package body ctx_pkg
2 as
3 procedure set_value(p_key in varchar2, p_value in varchar2)
4 as
5 begin
6 dbms_session.set_context('MYAPP_CTX', p_key, p_value);
7 end;
8 end;
9/
Package body created.
當應用程序從連接池獲取連接時,它只需設置所有上下文信息一次。然後在同一會話
SQL> begin
2 ctx_pkg.set_value('USERNAME', 'JCAVE');
3 ctx_pkg.set_value('IP_ADDRESS', '192.168.17.34');
4 end;
5/
PL/SQL procedure successfully completed.
後續調用和查詢可以只要求任何值存儲在上下文中。
SQL> select sys_context('MYAPP_CTX', 'USERNAME')
2 from dual;
SYS_CONTEXT('MYAPP_CTX','USERNAME')
--------------------------------------------------------------------------------
JCAVE
實際上,你幾乎肯定要在clear_context
程序添加到調用dbms_session.clear_context('MYAPP_CTX')
以清除任何值已在上下文中進行了設置,當連接返回到連接池,以避免無意中允許範圍內的包來自一個會話的信息泄漏到另一個會話中。您可能還會設計包含單獨程序的程序包,以便設置和獲取至少常用密鑰(用戶名,IP地址等),而不是使用'USERNAME'對多個位置進行硬編碼。爲了簡單起見,我使用了一個通用的set_value
方法。
這絕對不是標準,絕對不是一個好辦法。你需要傳遞什麼樣的「額外」數據(即用戶名等)? – Icarus
是的,我們需要通過用戶名,域名,IP地址。 – zaq