通过在自定义函数中捕获XMLTable()错误来查找问题XML值

发布于 2025-02-11 10:51:41 字数 2798 浏览 1 评论 0原文

我正在使用一个称为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

童话 2025-02-18 10:51:41

如果您的XML会返回一行,则可以使用:

with function test_xmltable(v_xml clob) return number
is
  v_code VARCHAR2(255);
  v_desc VARCHAR2(255);
begin
  SELECT code, description
  INTO   v_code, v_desc
  FROM   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; 

如果它将返回多行,则可以使用:

with function test_xmltable(v_xml clob) return number
is
  v_code SYS.ODCIVARCHAR2LIST;
  v_desc SYS.ODCIVARCHAR2LIST;
begin
  SELECT code, description
  BULK COLLECT INTO v_code, v_desc
  FROM   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; 

db<> fiddle 在这里

If your XML will return a single row, you can use:

with function test_xmltable(v_xml clob) return number
is
  v_code VARCHAR2(255);
  v_desc VARCHAR2(255);
begin
  SELECT code, description
  INTO   v_code, v_desc
  FROM   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; 

If it will return multiple rows, you can use:

with function test_xmltable(v_xml clob) return number
is
  v_code SYS.ODCIVARCHAR2LIST;
  v_desc SYS.ODCIVARCHAR2LIST;
begin
  SELECT code, description
  BULK COLLECT INTO v_code, v_desc
  FROM   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; 

db<>fiddle here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文