[英]Concatenate is not working for content of Oracle unified_audit_trail field SQL_TEXT
我正在尝试向 Oracle 视图统一审计跟踪的字段 SQL_TEXT 的内容添加(连接)一些字符串。 连接未完成 - 未添加字符串。
测试脚本如下。
declare
v_SP_record clob;
cursor c1 is select * from unified_audit_trail
where sql_text is not null
order by event_timestamp;
begin
for rec in c1 loop
v_SP_record :=
'USER: ' || rec.dbusername || ' '
|| 'TIME: ' || to_char(rec.event_timestamp) || ' '
|| 'SQL_TEXT: ' || rec.sql_text || '<CLOSE>' ;
dbms_output.put_line(v_SP_record);
end loop;
end;
检查输出我可以看到字符串部分<CLOSE>
没有添加到 v_SP_record。
输出示例(unified_audit_trail 中多行中的一些行)如下:
USER: SYS TIME: 15-NOV-21 01.37.46.289000 AM SQL_TEXT: -- Created on 6/20/2019 by ADMINISTRATOR
declare
begin
dbms_audit_mgmt.clean_audit_trail(
AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
USE_LAST_ARCH_TIMESTAMP => FALSE
);
end;
USER: OMEGACAEVDBA TIME: 15-NOV-21 01.42.49.679000 AM SQL_TEXT: select mdsys.GetMdsysEvent() from dual
USER: OMEGACAEVDBA TIME: 15-NOV-21 01.42.49.710000 AM SQL_TEXT: select sys.dbms_standard.dictionary_obj_type from dual
USER: OMEGACAEVDBA TIME: 15-NOV-21 01.42.49.741000 AM SQL_TEXT: select mdsys.GetMdsysEvent() from dual
USER: OMEGACAEVDBA TIME: 15-NOV-21 01.42.49.741000 AM SQL_TEXT: select sys.dbms_standard.dictionary_obj_type from dual
USER: OMEGACAEVDBA TIME: 15-NOV-21 01.42.49.757000 AM SQL_TEXT: -- Name = RUN1
grant drop any table to OMEGACAEVDEV1 with admin option
<CLOSE>
字符串不会添加到 rec.sql_text 之后。 此行为已在 Oracle 12c R2、18c 和 19c 上得到验证
SQL_TEXT 内容中的哪些字符会导致连接失败? 以及如何删除它们 - 或获得正确的结果?
此致
阿尔廷
串联正在发生。 似乎sql_text
以空字符终止,该空字符已被其他值和结果记录sql_text
。 连接后,空字符位于生成的字符串的中间。
基本上你最终会得到:
USER: ... SQL_TEXT: select mdsys.GetMdsysEvent() from dual<NUL><CLOSE>
^^^^^
null character, ASCII 0
如何处理取决于客户端(一些客户端不会显示完整的连接字符串;其他人会显示它但你将无法复制它;其他人可能只是显示它而不做任何奇怪的事情)和你做什么它。
由于空字符用于在许多地方(例如 C 字符串;但不是在 Oracle varchars 内部)标记可变长度字符串的结尾,因此它会导致您生成的字符串 - 在您的连接之后 - 在某处被截断就不足为奇了线。 在它被丢弃或至少被忽略并且不用于进一步处理之后的所有内容 - 在您的客户端或utl_tcp
或两者中。
您可以在连接后替换空字符:
v_SP_record := <your current concatenation>;
v_SP_record := replace(v_SP_record, chr(0), null)
或在与以下连接之前:
v_SP_record := ... || replace(rec.sql_text, chr(0), null) || '<CLOSE>';
或者您可以在连接之前从原始sql_text
值中修剪它,使用:
v_SP_record := ... || rtrim(rec.sql_text, chr(0)) || '<CLOSE>';
或者:
v_SP_record := ... || trim(trailing chr(0) from rec.sql_text) || '<CLOSE>';
我可能会使用其中一个修剪选项,最后一个对于稍后试图理解代码的人来说可能是最不言自明的(尽管解释为什么它仍然存在的注释当然仍然是一个好主意,无论您使用哪种方法) .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.