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

时间:2015-01-08 00:38:49

标签: plsql xml-parsing

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

<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>

谢谢

1 个答案:

答案 0 :(得分:0)

不是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

ClientSurname: Dijk 磁盘

2

3

ClientName: Jeffery Jim

ClientSurname: Dijks Diskett