【问题标题】:How to return multiple rows from Multiple XML nodes Combine with SQL Tables?如何从多个 XML 节点返回多行并结合 SQL 表?
【发布时间】:2021-07-28 12:05:41
【问题描述】:

我需要将 XML 和 SQL Server 表中的数据结合起来。我正在尝试这样做并面临以下错误。

消息 102,第 15 级,状态 1,第 52 行 “响应”附近的语法不正确。

XML...

set @sqlxml = N'<response xmlns="http://xyz.in/twa/cmm/decl/v2">
<identification>88762431</identification>
<type>RESPONSE</type>
<submitter><identifier>40134916C</identifier></submitter>
<functionalReference>TSW07389555IM1</functionalReference>
<transactionType>24</transactionType>
<attachDocument>
    <category>AAA</category>
    <mimeCode>application/pdf</mimeCode>
    <URI>16f15574-5d5a-4e83-b9ac-2151f10cf2eb</URI>
    <filename>XYZ_B2021_199.pdf</filename>
</attachDocument>
<attachDocument>
    <category>AAB</category>
    <mimeCode>text/plain</mimeCode>
    <URI>1511b476-a2be-4ae5-a54c-0a5dc14759b2</URI>
    <filename>XYZ_B2021_199_xml.txt</filename>
</attachDocument>
<additionalInformationICN><text>Please refer to attached XYZ for Directions</text></additionalInformationICN>
<issueDate>20210331113355</issueDate>
<overallDeclaration>
    <identification>88762431</identification>
    <functionalReference>TSW07389555IM1</functionalReference>
    <submitter>
        <identifier>40134916C</identifier>
    </submitter>
    <responsibleGovernmentAgency>XYZ</responsibleGovernmentAgency>
</overallDeclaration>
<status>
    <agency>XYZ</agency>
    <effectiveDate>20210331113355</effectiveDate>
    <name>B04</name>
    <releaseDate>20210331113355</releaseDate>
</status>
</response>'

SQL 脚本...

;WITH XMLNAMESPACES ('http://xyz.in/twa/cmm/decl/v2' AS ns)
SELECT distinct lv.[VERSION] LocationVersion,
lv.CHANGE_REASON LocationVersionChangeReason,
lv.CREATED_TIMESTAMP LocationVersionCreatedTimestamp,
lrd.CATEGORY,
lrd.MIME_TYPE as mimecode,
coalesce(lrd.[OBJECT_ID], lrd.FILENET_ID) as URI,
lrd.DOCUMENT_NAME as [FileName],
cast(lrd.SEQUENCE as bigint) sequence
response.value('(/response/status/agency/text())[1]','varchar(100)') as ResponseAgency,
response.value('(/response/issueDate/text())[1]','varchar(50)') as ResponseIssueDateTime,
response.value('(/response/additionalInformationICN/text/text())[1]','varchar(1000)') as ResponseClearanceInstructions
FROM DB.Location l
INNER JOIN DB.Location_RESPONSE lr ON l.Location_ENTITY_KEY = lr.Location_ENTITY_KEY
INNER JOIN DB.Location_RESPONSE_DOCUMENT lrd ON lr.Location_RESPONSE_KEY = lrd.Location_RESPONSE_KEY
LEFT OUTER JOIN DB.Location_VERSION lv on lr.Location_VERSION_KEY = lv.Location_VERSION_KEY
INNER JOIN DB.Location_RESPONSE lr2 on l.Location_ENTITY_KEY = lr2.Location_ENTITY_KEY
CROSS APPLY @sqlxml.nodes('/response') AS xmltable(response)
WHERE l.Llocation_ENTITY_KEY = 123456789

Sql 脚本工作正常,从数据库返回数据,不包括如下 XML...

;WITH XMLNAMESPACES ('http://xyz.in/twa/cmm/decl/v2' AS ns)
SELECT distinct lv.[VERSION] LocationVersion,
lv.CHANGE_REASON LocationVersionChangeReason,
lv.CREATED_TIMESTAMP LocationVersionCreatedTimestamp,
lrd.Category,
lrd.MIME_TYPE as Mimecode,
coalesce(lrd.[OBJECT_ID], lrd.FILENET_ID) as URI,
lrd.DOCUMENT_NAME as [FileName],
cast(lrd.SEQUENCE as bigint) [Sequence]
--response.value('(/response/status/agency/text())[1]','varchar(100)') as ResponseAgency,
--response.value('(/response/issueDate/text())[1]','varchar(50)') as ResponseIssueDateTime,
--response.value('(/response/additionalInformationICN/text/text())[1]','varchar(1000)') as ResponseClearanceInstructions
FROM DB.Location l
INNER JOIN DB.Location_RESPONSE lr ON l.Location_ENTITY_KEY = lr.Location_ENTITY_KEY
INNER JOIN DB.Location_RESPONSE_DOCUMENT lrd ON lr.Location_RESPONSE_KEY = lrd.Location_RESPONSE_KEY
LEFT OUTER JOIN DB.Location_VERSION lv on lr.Location_VERSION_KEY = lv.Location_VERSION_KEY
INNER JOIN DB.Location_RESPONSE lr2 on l.Location_ENTITY_KEY = lr2.Location_ENTITY_KEY
--CROSS APPLY @sqlxml.nodes('/response') AS xmltable(response)
WHERE l.Llocation_ENTITY_KEY = 123456789

结果...

有人可以帮忙吗?

提前致谢

【问题讨论】:

  • 你忘记了行尾的逗号 cast(lrd.SEQUENCE as bigint) 序列
  • Larnu 经常喜欢说...; 是语句终止符,而不是语句开始符。拥有;WITH 任何东西都是不好的形式。
  • 尝试改用WITH XMLNAMESPACES (default 'http://xyz.in/twa/cmm/decl/v2')
  • 还可以尝试从您的response.value() XPaths 中删除/response/ ... @sqlxml.nodes() 已经选择了/response 元素,因此/response/... 是多余的。
  • 不清楚为什么你有.nodes,只有一个&lt;response&gt;节点

标签: sql sql-server xml


【解决方案1】:

您对 XML 所做的操作称为粉碎。它将 XML 数据类型转换为矩形/关系格式。之后,您需要将其与其他一些数据库表中的其余数据加入

实现它的最简单方法是通过 CTE。您需要将结果集 rs.* 中的数据/列与其余的数据库表连接起来。

如下:

;WITH XMLNAMESPACES (DEFAULT 'http://xyz.in/twa/cmm/decl/v2'), rs AS
(
    SELECT c.value('(category/text())[1]','VARCHAR(50)') as Category,
        c.value('(mimeCode/text())[1]','VARCHAR(50)') as MimeCode,
        c.value('(URI/text())[1]','UNIQUEIDENTIFIER') as URI,
        c.value('(filename/text())[1]','VARCHAR(50)') as [FileName],
        c.value('(/response/status/agency/text())[1]','VARCHAR(100)') as ResponseAgency,
        c.value('(/response/issueDate/text())[1]','VARCHAR(100)') as ResponseIssueDateTime,
        c.value('(/response/additionalInformationICN/text/text())[1]','VARCHAR(100)') as ResponseClearanceInstructions
   FROM @sqlxml.nodes('/response/attachDocument') AS t(c)
)
SELECT * 
FROM rs INNER JOIN ...;

【讨论】:

  • 谢谢 Yitzhak.. 你能推荐任何好文章吗... 会有所帮助(或者一个例子会帮助你思考它)。
  • @SQLHoncho,请在 LinkedIn 上与我联系。我们将就这个主题进行交谈。
  • 完成并与您一起:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 2012-10-16
  • 2014-09-30
  • 1970-01-01
相关资源
最近更新 更多