2013-10-27 58 views
1

我想從包中定義的函數內部調用SYS.DBMS_RLS.ENABLE_POLICY()。 但它顯示了以下錯誤:在函數內調用DBMS_RLS.ENABLE_POLICY?

Error(19,16): PLS-00201: identifier 'SYS.DBMS_RLS' must be declared

代碼:

CREATE OR REPLACE PACKAGE BODY foopackage IS 
    FUNCTION foobar RETURN t_table PIPELINED IS 
    BEGIN 
     EXECUTE(SYS.DBMS_RLS.ENABLE_POLICY(-- error in this line 
      object_schema => 'foo', 
      object_name => 'bar', 
      policy_name =>'bar2', 
      enable => FALSE 
     )); 
     -- some more code 
     EXECUTE(SYS.DBMS_RLS.ENABLE_POLICY(-- error in this line 
      object_schema => 'foo', 
      object_name => 'bar', 
      policy_name =>'bar2', 
      enable => TRUE 
     )); 
     RETURN; 
    END; 
END foopackage; 

回答

2

首先,如果你想從程序B內部呼叫過程的,就沒有必要使用EXECUTE(這樣做會由於沒有EXECUTE程序,因此是錯誤的)。只需撥打其他程序。

CREATE OR REPLACE PACKAGE BODY foopackage IS 
    FUNCTION foobar RETURN t_table PIPELINED IS 
    BEGIN 
     SYS.DBMS_RLS.ENABLE_POLICY(-- error in this line 
      object_schema => 'foo', 
      object_name => 'bar', 
      policy_name =>'bar2', 
      enable => FALSE 
     ); 
     -- some more code 
     SYS.DBMS_RLS.ENABLE_POLICY(-- error in this line 
      object_schema => 'foo', 
      object_name => 'bar', 
      policy_name =>'bar2', 
      enable => TRUE 
     ); 
     RETURN; 
    END; 
END foopackage; 

更正此錯誤可能會也可能不會解決問題。如果仍然出現編譯錯誤,可能的問題是您正在創建定義者的權限存儲過程,但定義者(包的所有者)在DBMS_RLS程序包上沒有EXECUTE權限作爲直接授予用戶的權限。通過角色授予的權限在定義者權限存儲過程中不可用(儘管它們可能在會話中可用)。

儘管如此,您似乎不太可能嘗試執行問題DDL的過程調用,並且這會導致事務在函數內提交。這將使它很難調用函數,我認爲這是你打算調用它的方式。你試圖解決什麼問題?如果您試圖編寫繞過策略函數的代碼,那麼您真正想要做的就是修改策略函數,以便讓您的代碼通過執行諸如在策略上下文中設置覆蓋的方式來繞過它函數使用(假設它使用上下文)或通過授予包的所有者特權或以其他方式將旁路功能編碼到策略功能本身中。

+0

我同意賈斯汀:以編程方式關閉RLS策略是非常糟糕的做法。如果你需要運行一些不受政策約束的代碼,那麼你需要有一個特殊的用戶,並有適當的豁免。 – APC

+0

創建使用應用該策略的同一個表的策略謂詞時,要走的路是什麼? – blaze

+0

如何繞過功能進入策略功能? – blaze