【问题标题】:Expected UDT got NUMBER in Virtual Private Database Policy预期 UDT 在虚拟专用数据库策略中获得 NUMBER
【发布时间】:2014-08-13 13:29:37
【问题描述】:

我有以下问题: 我想对我的数据库中的表实施“行级安全策略”并添加此功能:

FUNCTION app_user_is_master_owner(
    schema_in IN VARCHAR2,
    object_in IN VARCHAR
)
RETURN VARCHAR2
IS  return_value VARCHAR2(100);
BEGIN
SELECT 'OWNER_FK = ' || 
    (SELECT mo.owner_id 
    FROM MASTER_OWNER mo
    WHERE upper(mo.owner_name) = SYS_CONTEXT('USERENV', 'SESSION_USER')) ||
    ' OR OWNER_FK IS EMPTY' 
    INTO return_value
    FROM DUAL;
RETURN return_value;
END app_user_is_master_owner;

我从 DBMS_RLS 中调用了 ADD_POLICY 以将其添加到其他策略中

 BEGIN
 DBMS_RLS.ADD_POLICY(
 object_schema => 'MY_SCHEMA',
 object_name => 'MASTER_DATA',
 policy_name => 'app_user_is_mo_policy',
 function_schema => 'MY_SCHEMA',
 policy_function => 'MY_RLS_POLICYS.app_user_is_master_owner',
 statement_types => 'SELECT, INSERT, UPDATE, DELETE'
 );
 END;

当我在 sql plus 中调用该函数而不将其添加为 RLS 策略时,将返回预期的“where”子句

SQL> select my_rls_policys.app_user_is_master_owner('A','A') from dual;
 MY_RLS_POLICYS.APP_USER_IS_MASTER_OWNER('A','A')
 --------------------------------------------------------------------------------
 OWNER_FK = 4000 OR OWNER_FK IS EMPTY

但如果我将其称为 VPD-Policy,则会出现此错误消息。

SQL> SELECT * FROM MASTER_DATA;
SELECT * FROM MASTER_DATA
                        *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected UDT got NUMBER

我猜这是因为结果是 Select 而不是 VARCHAR,但是将 TO_CHAR 添加到“select to_char(...) into return_value”和“return TO_CHAR(return_value)”似乎都不能解决问题。

其他政策也可以。

感谢您的帮助。

马蒂亚斯

【问题讨论】:

    标签: oracle plsql row-level-security


    【解决方案1】:

    尝试将所有者获取到一个变量,然后连接

    function app_user_is_master_owner(
        schema_in in varchar2,
        object_in in varchar
    ) return varchar2 
    is
        predicate   varchar2(100);
        owner_id    master_owner.owner_id%type;
    begin
        select  owner_id 
        into    owner_id
        from    master_owner
        where   upper(owner_name) = sys_context('userenv', 'session_user');
    
        predicate := '(owner_fk = ' || owner_id || ' or owner_fk is null)';
    
        return predicate;
    end app_user_is_master_owner;
    

    P.S 不确定 is empty 是什么意思...我将其更改为 is null

    【讨论】:

    • 还有两件事,为生成的字符串定义更大的大小,例如谓词(我通常使用 synamic string ~ varchar2(4001) 的限制)并为NO_DATA_FOUND 添加一个案例。
    • 我会考虑的,现在这只是我尝试制作的教程的一个示例。不过谢谢你的建议。
    猜你喜欢
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 2014-08-25
    • 2014-06-06
    相关资源
    最近更新 更多