我们有一个名为audit1的表。它有一个列'更改',其中包含XML作为blob。 xml如下所示。审计表基本上记录了通过我们的应用程序UI发生在其他表上的更改。
<c>
<f n="VersNo" b="1" a="2"/>
<f n="LstDate" b="20160215" a="20160217"/>
<f n="FileSweepId" b="Test" a="Test1"/>
</c>
我需要创建一个报告,列出自给定日期到某些表以来发生的所有更改。一旦我有了我感兴趣的audit1记录,我需要列出报告中的所有f节点。
即每个相关审计记录中的每个f节点都需要成为报表中的一行。
该报告由我们的应用生成。应用程序生成报告可以采取的措施之一是:
我想不出通过单个sql查询实现这一目标的方法。所以,我正在写一个存储过程的道路。
我面临的第一个问题是如何迭代过程中的f个节点。
其次,我需要弄清楚如何从out_cursor中的审计记录返回这些f节点以及其他信息。
BEGIN FOR item IN (SELECT auditno, xmltype(changes, 1) as changes, extract(xmltype(changes, 1), '/c/f') as fields from audit1 where runlistno is null and rownum < 2 ) LOOP dbms_output.put_line(item.auditno || ' ' || item.changes.getStringVal() || ' ' || item.fields.getStringVal()); -- stumped about how to iterate over the f nodes --FOR field in ('select extractvalue(object_value, '/') x FROM TABLE(XMLSequence(' + item.fields.getStringVal() + ') ') FOR field in (select f from XMLTable('for $i in / return $i' passing item.fields columns f varchar2(200) path 'f')) LOOP dbms_output.put_line(field.f); END LOOP; END LOOP; END;
上面的PL / SQL目前错误:
ORA-19114:XPST0003 - 解析XQuery表达式时出错: LPX-00801:$ i中的$ i in / return $ i的XQuery语法错误 - ^ ORA-06512:第6行
答案 0 :(得分:0)
我能够通过将plsql修改为:
来消除错误BEGIN
FOR item IN (SELECT auditno, xmltype(changes, 1) as changes, extract(xmltype(changes, 1), '/c/f') as fields from audit1 where runlistno is null and rownum < 2 )
LOOP
dbms_output.put_line('parsing fields from: ' || item.fields.getStringVal());
dbms_output.put_line('name||beforevalue||aftervalue');
FOR field in (select n, b, a from XMLTable('//f' passing item.fields columns n varchar2(30) path '@n', b varchar(30) path '@b', a varchar(30) path '@a' ))
LOOP
dbms_output.put_line(field.n || '|| ' || field.b || '|| ' || field.a);
END LOOP;
END LOOP;
END;
所以我现在能够迭代字段。但还不确定如何从sys ref游标中的字段返回信息。上面的plsql输出示例:
parsing fields from: <f n="VersNo" b="1" a="2"/><f n="LstDate" b="20160215" a="20160217"/><f n="FileSweepId" b="Test" a="Test1"/>
name||beforevalue||aftervalue
VersNo|| 1|| 2
LstDate|| 20160215|| 20160217
FileSweepId|| Test|| Test1
答案 1 :(得分:0)
为什么不使用简单的SQL,使用链接的XMLTable
函数提取所需的字段?
看一下简单的例子:
CREATE TABLE audit1(
changes CLOB
);
INSERT INTO audit1 VALUES( '<c>
<f n="VersNo" b="1" a="2"/>
<f n="LstDate" b="20160215" a="20160217"/>
<f n="FileSweepId" b="Test" a="Test1"/>
</c>'
);
INSERT INTO audit1 VALUES(
'<c>
<f n="VersNo" b="22" a="32"/>
<f n="LstDate" b="20160218" a="2016020"/>
<f n="FileSweepId" b="Test 555" a="Test1234"/>
</c>'
);
commit;
现在:
SELECT rec_no, rn, n, b, a
FROM ( select rownum rec_no, a.* FROM audit1 a ),
XMLTable( '/c'
passing xmltype( changes )
columns f_fields xmltype path './f'
) x1,
XMLTable( '/f'
passing x1.f_fields
columns rn for ordinality,
n varchar2(20) path './@n',
b varchar2(20) path './@b',
a varchar2(20) path './@a'
)
REC_NO RN N B A
---------- ---------- -------------------- -------------------- --------------------
1 1 VersNo 1 2
1 2 LstDate 20160215 20160217
1 3 FileSweepId Test Test1
2 1 VersNo 22 32
2 2 LstDate 20160218 2016020
2 3 FileSweepId Test 555 Test1234
6 rows selected