如何在T-SQL中遍历XML字段的节点?

12

我有一个XML字段,其中至少会有一个名为"ChildNode"的节点,但可能会有更多。我试图在T-SQL中创建一个循环,以获取每个ChildNode的XML作为VarChar(1000),并对其进行一些逻辑处理。当我尝试以下操作时...

...
SET @intIterator=1 

SET @strValue = (SELECT XMLField.value('(/RootNode/ParentNode/ChildNode)[' + CAST(@intIterator AS VARCHAR(2)) + ']', VARCHAR(1000)) WHERE PrimaryKeyField=@intID)

WHILE LEN(@strValue) > 0
   BEGIN

      --LOGIC with @strValue not shown.
      @intIterator = @intIterator + 1
      @strValue = (SELECT XMLField.value('(/RootNode/ParentNode/ChildNode)[' + CAST(@intIterator AS VARCHAR(2)) + ']', VARCHAR(1000)) WHERE PrimaryKeyField=@intID)

   END

我遇到了以下错误: xml数据类型方法"value"的参数1必须是字符串字面量。

我知道当我尝试将@intIterator用作value方法中的参数时,它会因为需要一个字符串字面量而不是一个变量而爆炸,但是如何逐个迭代T-SQL中的子节点呢?

2个回答

19

我不知道你的XML长什么样子,但你可能需要采用一种不同的方法 - 不要尝试迭代、循环或类似的东西 - 而是使用XQuery中的.nodes()函数:

SELECT 
    Child.value('(SomeElement)[1]', 'int'),
    Child.value('(SomeOtherElement)[1]', 'Varchar(50)')
FROM
    XMLField.nodes("/RootNode/ParentNode/ChildNode") AS N(Child)

这基本上将迭代/循环留给了XQuery,您根本不需要处理任何索引之类的东西.....


2
非常正确。你正在使用关系型数据库。考虑集合逻辑,而不是循环和过程逻辑。 - Chris Dickson
抱歉 @marc_s,您能编辑一下您的帖子吗?'Varchar(50)'), 多了一个逗号。我无法编辑,因为它只是一个符号。 - new2ios

9

仍然可能需要查询该问题的答案无法解决的子元素。您可以使用sql:variable来满足字符串文字参数的nodes()要求,以迭代地查询特定节点的子元素。

DECLARE @iterator = 1

SELECT 
    Child.value('(SomeElement)[1]', 'int'),
    Child.value('(SomeOtherElement)[1]', 'Varchar(50)'),
FROM
    XMLField.nodes("/RootNode/ParentNode[sql:variable("@iterator")]/ChildNode") AS N(Child)

XQuery [value()]: 'value()' 需要单例(或空序列),发现操作数类型为 'xdt:untypedAtomic *'。 - user2338150

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接