繁体   English   中英

Concatenate 不适用于 Oracle Unified_audit_trail 字段 SQL_TEXT 的内容

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM