在 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
客户姓名:杰弗里:吉姆
客户姓氏:Dijks:Diskett
我有一个日志 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
客户姓名:杰弗里:吉姆
客户姓氏:Dijks:Diskett