Oracle VPD遇ORA-28113错误:基于用户过滤特定格式列值问题
问题分析与解决方案
错误原因
- 谓词语法错误:原代码中
l_predicate := 'DOMAIN != |3721|';里的|3721|未加单引号,Oracle会将其视为无效标识符,直接触发ORA-28113错误。由于DOMAIN存储的是字符串类型值(如|3721|),必须用单引号包裹常量值,且Oracle中字符串内的单引号需用双单引号转义。 - 特权用户谓词未定义:当用户是TOM时,
l_predicate未赋值,返回NULL会导致行级安全策略生成无效过滤条件,引发意外的行限制或错误。
修正后的代码
1. 重新创建策略函数
CREATE OR REPLACE FUNCTION AUDITDOMAIN_SECURE_FNC (p_schema VARCHAR2, p_obj VARCHAR2) RETURN VARCHAR2 AS l_user VARCHAR2 (20); l_predicate VARCHAR2 (100); BEGIN l_user := USER; -- 直接赋值,无需额外查询DUAL表 IF l_user NOT IN ('TOM') THEN -- 匹配准确的字符串格式,用双单引号转义内部单引号 l_predicate := 'DOMAIN != '' |3721| '''; ELSE -- 特权用户TOM返回永真条件,不限制任何行 l_predicate := '1=1'; END IF; RETURN l_predicate; END AUDITDOMAIN_SECURE_FNC; /
2. 重新添加行级安全策略
BEGIN DBMS_RLS.drop_POLICY (object_schema => 'Schema1', object_name => 'RT_TABLE', policy_name => 'AUDIT_DOMAINSECURE'); END; / BEGIN DBMS_RLS.add_policy (object_schema => 'SCHEMA1', object_name => 'RT_TABLE', policy_name => 'AUDIT_DOMAINSECURE', function_schema => 'SCHEMA1', policy_function => 'AUDITDOMAIN_SECURE_FNC', statement_Types => 'SELECT', sec_relevant_cols => 'DOMAIN,TABLE_ID', sec_relevant_cols_opt => DBMS_RLS.ALL_ROWS); -- 显式指定,确保所有行的目标列都被隐藏 END; /
关键说明
- 字符串匹配规则:如果需要过滤其他
|数字|格式的值(如|1234|),只需替换谓词中的' |3721| '为目标字符串即可,注意保持前后空格和竖线的格式完全一致。 - 列隐藏逻辑:
sec_relevant_cols_opt => DBMS_RLS.ALL_ROWS参数确保非特权用户无论行是否被过滤,都无法看到DOMAIN和TABLE_ID列,完全符合隐藏列的需求。 - 性能优化:用
l_user := USER替代SELECT USER INTO l_user FROM DUAL,避免不必要的SQL查询,提升策略函数执行效率。
内容的提问来源于stack exchange,提问作者Cindy
相关产品推荐
相关产品推荐

