2013-10-27 56 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