ORA-19279: XPTY0004 - XQuery 动态类型不匹配: 多行具有相同名称的预期单例序列

Posted

技术标签:

【中文标题】ORA-19279: XPTY0004 - XQuery 动态类型不匹配: 多行具有相同名称的预期单例序列【英文标题】:ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence on multiple rows with same name 【发布时间】:2021-10-11 04:55:54 【问题描述】:

我正在尝试解析转换为 xml 的 SOAP 请求响应。 请注意,这是我第一次使用这种查询。 它的结构如下:

<soap:Body>
    <ns2:findDocumentsResponse xmlns:ns2="http://www.datengut.de">
        <ecmDocumentInfo>
            <id>53CA3873CCFCC44FB5FE99047E5ED04E000000000000</id>
            <fields>
                <entry>
                    <key>SYSFILENAMES</key>
                    <value>
                        <name>SYSFILENAMES</name>
                        <type>STRING</type>
                        <values xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">test_file1.pdf</values>
                        <values xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">test_file2.pdf</values>
                        <values xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">test_file3.pdf</values>
                        <values xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">test_file4.pdf</values>
                        <isMulti>true</isMulti>
                    </value>
                </entry>
            </fields>
    ....

我使用的 SQL 查询如下:

SELECT 
    t."key", f."value"
FROM
    XMLTABLE(
        xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as "soap",'http://www.datengut.de' as "ns2"),
        '/soap:Envelope/soap:Body/ns2:findDocumentsResponse/ecmDocumentInfo/fields/entry'
    PASSING xmltype.createXML('[see structure above]') 
    COLUMNS
        "key" varchar2(4000) PATH 'key',
        "path" XMLType path 'value'
    ) t
    CROSS JOIN XMLTABLE(
        'value'
        PASSING t."path"
        COLUMNS
            "value" varchar2(4000) PATH '.'
    ) f

我收到的输出:

KEY                 VALUE
------------------- ---------------------------------------
SYSFILENAMES        SYSFILENAMESSTRINGtest_file1.pdftest_file2.pdftest_file3.pdftest_file4.pdftrue

我期望收到的输出:

KEY                 VALUE
------------------- ---------------------------------------
SYSFILENAMES        test_file1.pdf
SYSFILENAMES        test_file2.pdf
SYSFILENAMES        test_file3.pdf
SYSFILENAMES        test_file4.pdf

当我换行时:

"value" varchar2(4000) PATH '.'

"value" varchar2(4000) PATH 'values'

我收到“ORA-19279:XPTY0004 - XQuery 动态类型不匹配:预期的单例序列”错误消息。当 PATH 为 '.' 时不会出现错误但随后我在同一行中收到值条目的每个值。我只想显示预期结果部分中显示的文件名。 如何交叉加入第二个 XMLTABLE f 以接收我的预期输出。 非常感谢。

【问题讨论】:

【参考方案1】:

您只需将 /values 添加到您的第二个 XPath:

    CROSS JOIN XMLTABLE(
        'value/values'
        PASSING t."path"
        COLUMNS
            "value" varchar2(4000) PATH '.'
    ) f
key value
SYSFILENAMES test_file1.pdf
SYSFILENAMES test_file2.pdf
SYSFILENAMES test_file3.pdf
SYSFILENAMES test_file4.pdf

您也可以在一个 XMLTable 调用中执行此操作,方法是首先查找值并返回树上以获取密钥(这在 11.2.0.2 或 11.2.0.3 中无法正常工作,但在更高版本中可以正常工作) :

SELECT 
    t."key", t."value"
FROM
    XMLTABLE(
        xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as "soap",'http://www.datengut.de' as "ns2"),
        '/soap:Envelope/soap:Body/ns2:findDocumentsResponse/ecmDocumentInfo/fields/entry/value/values'
    PASSING xmltype.createXML('[see structure above]') 
    COLUMNS
        "key" varchar2(4000) PATH './../../key',
        "value" varchar2(4000) path '.'
    ) t

db<>fiddle 带有完整的 XML(添加了结束标记,以及带有命名空间声明的 soap:Envelope 包装器)。

如果您可能拥有并且想要报告没有值的键,那么您可以返回到两个 XMLTable 版本,但使用 outer apply 而不是 cross join;但这要到 12 点才能使用。

顺便说一句,您不必显式使用createXML',只需使用PASSING xmltype('[see structure above]')。如果可能的话,我会避免引用标识符;如果它们真的必须是小写的,那么我会在整个查询中不加引号,只在最终的外部选择列表中添加一个带引号的别名。

【讨论】:

只要有 11g 标签,outer apply 就不是一个选项。有趣的是your own comment 关于访问父节点是:这适用于 11.2.0.4、12.1.0.2 和 12.2.0.1。但它在 11.2.0.2 (dbfiddle) 中确实为空,我猜这是该版本中的一个错误 是的,我错过了那个标签;并且在 11.2.0.2 中无法正常上树,稍后修复。【参考方案2】:

它适用于:

SELECT 
    t."key", f."value"
FROM
    XMLTABLE(
        xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as "soap",'http://www.datengut.de' as "ns2"),
        '/soap:Envelope/soap:Body/ns2:findDocumentsResponse/ecmDocumentInfo/fields/entry/value'
    PASSING xmltype.createXML('[see structure above]') 
    COLUMNS
        "key" varchar2(4000) PATH 'name',
        "path" XMLType path 'values'
    ) t
    CROSS JOIN XMLTABLE(
        'values'
        PASSING t."path"
        COLUMNS
            "value" varchar2(4000) PATH '.'
    ) f

【讨论】:

以上是关于ORA-19279: XPTY0004 - XQuery 动态类型不匹配: 多行具有相同名称的预期单例序列的主要内容,如果未能解决你的问题,请参考以下文章

COMP0004 Coursework Part III

cmake:前导或尾随空格(策略 CMP0004)

python每日一练:0004题

Xamarin部署错误HE0004 DADocSetManagement

0004 - DataNode工作机制解析

0004 plsql的安装