【问题标题】:How to loop through xml data that is stored in XML format in SQL Server?如何遍历以 XML 格式存储在 SQL Server 中的 xml 数据?
【发布时间】:2017-01-11 16:11:24
【问题描述】:

我有一个 SQL 查询当前获取存储在我的数据库中的列中的值,如下所示:

SELECT 
    @filevalue = (CAST(REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '') AS XML).value('(//value)[1]', 'NVARCHAR(max)')), 
    @filecontent = de.ENVIRONMENT_ID
FROM
    dbo.DEPLOYMENT_ENVIRONMENT AS de
WHERE
    de.ENVIRONMENT_ID = CAST(REPLACE(CAST(@filevalue AS numeric(19, 0)), 'encoding="uft-16"', '') AS numeric(19, 0))

.value('(//value)[1]') 所在的部分是问题所在,因为有时会有多个值节点。我试图将一个计数器和值节点连接在一起,但是当我这样做时,返回的错误是值需要是一个字符串而不是 varchar:.value(@ValueNodes, 'NVARCHAR(max)'))

那么我怎样才能成功地循环通过 xml 来获得我的结果呢?我这样做的问题是第一个值并不总是我需要的并且会给出错误(空值并且无法转换类型)。

【问题讨论】:

  • 您需要存储所有值吗?或者只是循环,直到找到所需的?
  • 不是必需的,但所需的值可以是任何值加上我认为的最大节点数为 5(我看到的大多数是 3),所以如果它将它们全部存储起来可能会更好。

标签: sql-server xml


【解决方案1】:

您可以使用深度搜索XPath,它会找到所有<value>-nodes,无论它们在哪里。您在开始时使用双 // 来执行此操作。以下将提取每个<value> 中的所有text() 以及父节点名称:

DECLARE @xml XML=
N'<root>
  <value>test1</value>
  <SomeParent>
    <value>test in parent</value>
    <value>one more in parent</value>
  </SomeParent>
  <value>One more on first level</value>
</root>';

SELECT val.value(N'(./text())[1]','nvarchar(max)') AS TheValueInValue
      ,val.value(N'local-name(..)','nvarchar(max)') AS ParentNode
FROM @xml.nodes(N'//value') AS Each(val)

结果

TheValueInValue           ParentNode
test1                     root
test in parent            SomeParent
one more in parent        SomeParent
One more on first level   root

更新

...当我从列中获取 xml 时

这是一次盲目的飞行,但你可能需要这样的东西:

WITH Casted AS
(
    SELECT 
         TheXML = CAST(REPLACE(CAST(de.TRIGGERS_XML_DATA AS VARCHAR(MAX)), 'encoding="utf-16"', '') AS XML)
        ,de.ENVIRONMENT_ID
    FROM
        dbo.DEPLOYMENT_ENVIRONMENT AS de
)
SELECT Casted.ENVIRONMENT_ID
      ,val.value(N'(./text())[1]','nvarchar(max)') AS TheValueInValue
      ,val.value(N'local-name(..)','nvarchar(max)') AS ParentNode
FROM Casted
CROSS APPLY TheXML.nodes(N'//value') AS Each(val)

【讨论】:

  • 酷我可以基​​本上做到这一点@xml = de.TRIGGERS_XML_DATA(我知道现在是为了使该值等于该值,但只是为了快速)因为我从列中获取 xml 跨度>
猜你喜欢
  • 2020-11-18
  • 2016-09-29
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多