通过在自定义函数中捕获XMLTable()错误来查找问题XML值
我正在使用一个称为 gdb_items_vw 在clob列中具有XML数据。
我可以使用以下查询从XML列中提取数据( source> source> source> ):
select
x.code,
x.description,
i.name as domain_name
from
sde.gdb_items_vw i
cross apply xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(i.definition)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
) x
DOMAIN_NAME CODE DESCRIPTION
-------------------- -------------------- ----------------------------------------
ATN_MATERIAL A ASPHALT
ATN_MATERIAL O ASPHALT CAPPING
ATN_MATERIAL B BRICK
当我在SQL Developer中运行该查询时,它不会错误地运行,但这仅仅是因为它仅选择前50行。
如果我尝试在所有行上运行查询(通过CTRL+END),那么它会引发一个错误:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00007: unexpected end-of-file encountered
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at line 1
31011. 00000 - "XML parsing failed"
*Cause: XML parser returned an error while trying to parse the document.
*Action: Check if the document to be parsed is valid.
因此,我想确定哪些特定行会导致该错误。
如 @mt0 在相关帖子中,我们可以通过:我们可以找到问题行:
创建一个函数来包装引起问题并在功能中捕获异常的调用。
我已经尝试调整 @MT0的功能:
with function test_xmltable(v_xml clob) return number
is
temp xmltype;
begin
temp := xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(v_xml)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
);
return 1;
exception
when others then
return 0;
end;
select
i.name as domain_name,
test_xmltable(i.definition)
from
sde.gdb_items_vw i
where
test_xmltable(i.definition) = 0;
但是我必须做错了什么,因为我遇到了一个错误:
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
*Cause:
*Action:
Error at Line: 1 Column: 15
如何找到问题XML值?
I'm using an Oracle 18c view called GDB_ITEMS_VW that has XML data in a clob column.
I can extract data from the XML column using the following query (source):
select
x.code,
x.description,
i.name as domain_name
from
sde.gdb_items_vw i
cross apply xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(i.definition)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
) x
DOMAIN_NAME CODE DESCRIPTION
-------------------- -------------------- ----------------------------------------
ATN_MATERIAL A ASPHALT
ATN_MATERIAL O ASPHALT CAPPING
ATN_MATERIAL B BRICK
When I run that query in SQL Developer, it runs without errors, but that's just because it's only selecting the first 50 rows.
If I try to run the query on all rows (via CTRL+END), then it throws an error:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00007: unexpected end-of-file encountered
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at line 1
31011. 00000 - "XML parsing failed"
*Cause: XML parser returned an error while trying to parse the document.
*Action: Check if the document to be parsed is valid.
So I want determine what specific rows are causing that error.
As mentioned by @MT0 in a related post, we can find the problem rows by:
Creating a function to wrap the call that is causing issues and catch the exception in the function.
I've attempted to adapt @MT0's function:
with function test_xmltable(v_xml clob) return number
is
temp xmltype;
begin
temp := xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(v_xml)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
);
return 1;
exception
when others then
return 0;
end;
select
i.name as domain_name,
test_xmltable(i.definition)
from
sde.gdb_items_vw i
where
test_xmltable(i.definition) = 0;
But I must be doing something wrong, because I'm getting an error:
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
*Cause:
*Action:
Error at Line: 1 Column: 15
How can I find the problem XML values?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您的XML会返回一行,则可以使用:
如果它将返回多行,则可以使用:
db<> fiddle 在这里
If your XML will return a single row, you can use:
If it will return multiple rows, you can use:
db<>fiddle here