在 Pl/Sql 中解析 xml 格式的大文本

Parsing large text in xml format in Pl/Sql

我有一个日志 table,table 有一个 varchar2 字段,其中包含 xml 字符串,如下所示: 在此示例中,ClientName 属性未更改,但 Clientsurname 已更改。 我想捕获更改的列及其以前的值和新值。 日志 table 包含数百万条记录。 您可以建议使用哪种方法来有效地解析此数据?

<r>
   <columntag nameattribute="ClientName">
      <new_value>Jeffrey</new_value>
      <previous_value>Jeffrey</previous_value>
   </columntag>
   <columntag nameattribute="ClientSurname">
      <new_value>Dijk</new_value>
      <previous_value>Disk</previous_value>
   </columntag>
</r>

谢谢

不能 100% 确定以下是您所追求的,但它应该会给您一些关于如何去做的想法。希望对你有帮助

CREATE TABLE "RM4SERV"."LOG_TEST" ( "TESTLOG" VARCHAR2(4000 BYTE))

Insert into RM4SERV.LOG_TEST (TESTLOG) values ('<r><columntag nameattribute="ClientName"><new_value>Jeffery</new_value><previous_value>Jeffery</previous_value> </columntag><columntag nameattribute="ClientSurname"><new_value>Dijk</new_value><previous_value>Disk</previous_value></columntag></r>');
Insert into RM4SERV.LOG_TEST (TESTLOG) values ('<r><columntag nameattribute="ClientName"><new_value>Jeffery</new_value><previous_value>Jeffery</previous_value> </columntag><columntag nameattribute="ClientSurname"><new_value>Disk</new_value><previous_value>Disk</previous_value></columntag></r>');
Insert into RM4SERV.LOG_TEST (TESTLOG) values ('<r><columntag nameattribute="ClientName"><new_value>Jeffery</new_value><previous_value>Jim</previous_value> </columntag><columntag nameattribute="ClientSurname"><new_value>Dijks</new_value><previous_value>Diskett</previous_value></columntag></r>');

declare

v_logrec varchar2(4000) := null;  
v_recnum number := 0;

cursor c_logs is
select testlog from log_test;

cursor c_records is 
select extractValue(x.column_value, '/columntag/@nameattribute') as column_name,
         extractValue(x.column_value, '/columntag/new_value') as new_value,
         extractValue(x.column_value, '/columntag/previous_value') as previous_value
from TABLE(XMLSequence(extract(xmltype.createxml(v_logrec), '//columntag'))) x
where extractValue(x.column_value, '/columntag/new_value') != extractValue(x.column_value, '/columntag/previous_value');


begin
for v_log in c_logs loop
  v_logrec := v_log.testlog;
  v_recnum := v_recnum + 1;
  dbms_output.put_line(v_recnum);

  for v_rec in c_records loop
     SYS.dbms_output.put_line(v_rec.column_name || '  :  *' || v_rec.new_value || '*  :  *' || v_rec.previous_value || '*');
  end loop;

end loop;
end;

这会给你下面的输出(所以姓氏在第一条记录中不同,在第二条记录中没有什么不同,在第三条记录中都不同)...

1

客户姓氏:Dijk磁盘

2

3

客户姓名:杰弗里吉姆

客户姓氏:DijksDiskett