Oracle 12c中DBMS_REDACT正则脱敏与regexp_replace行为差异咨询
Oracle 12c DBMS_REDACT正则脱敏非匹配行返回NULL的原因及解决办法
问题原因
Oracle的DBMS_REDACT使用REGEXP类型脱敏策略时,和普通REGEXP_REPLACE函数的行为存在核心差异:
REGEXP_REPLACE在正则表达式不匹配目标字符串时,默认返回原字符串;- 而
DBMS_REDACT.REGEXP策略仅在正则匹配成功时返回替换后的内容,如果匹配失败,会直接返回NULL,这就是非匹配行(如ZZZZZ)丢失的原因。
解决办法
要让非匹配行保留原内容,需要调整正则表达式,使其能覆盖所有字符串场景,同时在替换规则中区分匹配与非匹配的情况:
修改脱敏策略的regexp_pattern和regexp_replace_string参数:
DBMS_REDACT.ADD_POLICY( object_schema=>'SCOTT', object_name=>'TABLE1', policy_name=>'test_redact_policy', column_name=>'C_NAME', function_type=>DBMS_REDACT.REGEXP, expression=>'1=1', enable=>TRUE, regexp_pattern=>'^(YYY)(.*)$|(.*)', -- 匹配YYY开头的行,或所有其他行 regexp_replace_string=>'XXX\2\3' -- 匹配成功时替换为XXX+后续内容,否则保留原字符串 );
原理说明:
^(YYY)(.*)$匹配以YYY开头的字符串,捕获组1为YYY,捕获组2为后续内容;|(.*)匹配所有未被第一个规则命中的字符串,捕获组3为整个原字符串;- 替换字符串
XXX\2\3中,匹配第一个分支时\3为空,结果为XXX+后续内容;匹配第二个分支时\1和\2为空,结果就是\3对应的原字符串。
设置完成后,再次执行select c_name from table1;即可得到预期结果:
c_name --- XXX NNN ZZZZZ
内容的提问来源于stack exchange,提问作者Alexander Mitenko
相关产品推荐
相关产品推荐

