1

我正在尝试从包中定义的函数内部调用 SYS.DBMS_RLS.ENABLE_POLICY()。但它显示以下错误:

错误(19,16):PLS-00201:必须声明标识符“SYS.DBMS_RLS”

代码:

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;
4

1 回答 1

2

首先,如果您想从过程 B 中调用过程 A,则无需使用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;

更正此错误可能会也可能不会解决问题。如果您仍然遇到编译错误,则可能的问题是您正在创建定义者权限存储过程,但定义者(包的所有者)没有对包的EXECUTE权限DBMS_RLS作为直接授予用户的权限。通过角色授予的特权在定义者的权限存储过程中不可用(尽管它们可能在会话中可用)。

但是,退后一步,您似乎不太可能真的想尝试执行该问题DDL并导致事务在函数内部提交的过程调用。这将使以我认为您打算调用它的方式调用该函数变得非常困难。您要解决的问题是什么?如果您正在尝试编写绕过策略功能的代码,您似乎真正想要做的是修改策略功能,以便通过执行诸如在策略上下文中设置覆盖等操作来允许您的代码绕过它函数使用(假设它使用上下文)或通过授予包的所有者EXEMPT ACCESS POLICY特权或以其他方式将绕过功能编码到策略函数本身中。

于 2013-10-27T06:21:11.350 回答