ORA-19279: XPTY0004 - XQuery 动态类型不匹配: 具有相同名称的多行上的预期单例序列
ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence on multiple rows with same name
我正在尝试解析到 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 以接收我预期的输出。
非常感谢。
您只需将 /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
带有命名空间声明的包装器)。
如果您可能拥有并且想要报告没有值的键,那么您可以返回到双 XML 表版本,但使用 outer apply
而不是 cross join
;但这要到 12 点才可用。
顺便说一下,您不必明确使用 createXML
',您可以直接使用 PASSING xmltype('[see structure above]')
。如果可能的话,我会避免引用标识符;如果它们真的必须是小写的,那么我会在整个查询中不加引号,只在最终的外部 select 列表中添加一个带引号的别名。
它适用于:
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
我正在尝试解析到 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 以接收我预期的输出。 非常感谢。
您只需将 /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
带有命名空间声明的包装器)。
如果您可能拥有并且想要报告没有值的键,那么您可以返回到双 XML 表版本,但使用 outer apply
而不是 cross join
;但这要到 12 点才可用。
顺便说一下,您不必明确使用 createXML
',您可以直接使用 PASSING xmltype('[see structure above]')
。如果可能的话,我会避免引用标识符;如果它们真的必须是小写的,那么我会在整个查询中不加引号,只在最终的外部 select 列表中添加一个带引号的别名。
它适用于:
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