今天開發人員問我知不知道RESTRICT_REFERENCES()的功能,我也是第一次看到,所以到google尋找並記錄下來。
PRAGMA RESTRICT_REFERENCES(),它可以看做是對子程式做權限的控管,檢查子程式的純度(PURITY)。 可以避免例如A在DML上呼叫函式時,B因為不知情而修改該函式,雖然B在編譯上沒有問題,但是卻因為觸發到DML限制,進而導致A原本正常的DML發生錯誤。
語法:PRAGMA RESTRICT_REFERENCES(function_name | default , )RNDS, WNDS, RNPS, WNPS) | , TRUST);
RNDS,WNDS,RNPS,WNPS可以同時設定。但設定參數值為TRUST時,其它的值則全部失效。
function_name:應用的function
DEFAUT:是指應用在package的所有子程式、函式。
RNDS(Read No Database State):不能讀取任何資料庫的資訊,包括任何的表,連dual這個表也不行
RNPS(Read No Package State):不能讀取任何package的狀態資訊,如變數等。
WNDS(Write No Database State):不能在資料庫寫入任何資料(即不能修改表)。
WNPS(Write No Package State):不能向package寫入任何資訊(例如不能修改package變數的值)
TRUST,指出子程式是可以相信,故不受限。這個選項通常是用來PL/SQL在呼叫外部函數(如JAVA)時,因為PL/SQL是無法對外部函數進行限制。
範例:
create or replace package pkg_test is a number := 543; function test01 return number; function test02 return number; pragma restrict_references(test01, wnps); pragma restrict_references(test02, wnps); end; create or replace package body pkg_test is function test01 return number as begin a := 123; return a; end; function test02 return number as begin return a + 10 ; end; function test03 return number as b number ; begin b := 123; return b; end; function test04 return number as begin a := 9999; return a; end; end pkg_test;
test01變更了package的變數a的值,故編譯錯誤:PLS-00452: Subprogram 'TEST01' violates its associated pragma
test02只使用變數值,故未被限制;
test03則未使用到package的變數,而是使用function內部的變數,所以未被限制住
test04因為未定義restrict_references,故可以變更a的值