Как перебирать узлы поля XML в T-SQL? - PullRequest
8 голосов
/ 15 февраля 2011

У меня есть поле XML, которое, как я знаю, будет содержать хотя бы один "ChildNode", но, возможно, больше. Я пытаюсь сделать цикл в T-SQL, который будет получать XML каждого ChildNode как 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

Я получаю следующую ошибку: Аргумент 1 метода типа данных xml «value» должен быть строковым литералом.

Я знаю, что это взрывается, когда я пытаюсь использовать @intIterator в методе value, так как ему требуется строковый литерал вместо переменной, но тогда как я могу перебирать дочерние узлы один за другим в T-SQL?

Ответы [ 2 ]

15 голосов
/ 15 февраля 2011

Я понятия не имею, как выглядит ваш XML, но вам, вероятно, придется использовать другой подход - не пытайтесь выполнять итерации, циклы и тому подобное - вместо этого используйте функцию .nodes() в XQuery:

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

Это в основном оставляет итерацию / цикл для XQuery, и вам вообще не нужно возиться с индексами или чем-то подобным .....

6 голосов
/ 23 сентября 2011

По-прежнему может возникнуть необходимость запрашивать подэлементы, которые не может решить ответ на этот вопрос. Вы можете просто использовать sql: variable для удовлетворения требованиям узла () строкового литерального аргумента для итеративного запроса подэлементов определенного узла.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...