2011-02-15 17 views
8

Tengo un campo XML que sé que tendrá al menos un "ChildNode", pero posiblemente más. Estoy tratando de hacer un ciclo en T-SQL que obtenga el XML de cada ChildNode como VarChar (1000) y hacer algo de lógica con él. Cuando intento el siguiente ...¿Cómo puedo iterar a través de los Nodos de un campo XML en T-SQL?

... 
SET @intIterator=1 

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

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 [email protected]) 

    END 

me sale el siguiente error: El argumento 1 del "valor" de datos xml método de tipo debe ser una cadena literal.

Sé que está explotando cuando trato de usar @intIterator en el método de valor, ya que quiere una cadena literal en lugar de una variable, pero ¿cómo puedo iterar a través de los nodos secundarios uno por uno en T-SQL ?

Respuesta

14

no tengo idea de lo que el código XML se parece, pero es probable que tenga que utilizar un enfoque diferente - no trate de repetir y bucle y cosas por el estilo - en lugar de utilizar la función .nodes() en XQuery:

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

que, básicamente, deja la iteración/bucle de XQuery y que no tiene que perder el tiempo con índices ni nada de eso en absoluto .....

+2

Muy bien. Estás en una base de datos relacional. Piensa en lógica basada en conjuntos, no en bucles y en lógica de procedimientos. –

+0

Lo siento @marc_s, ¿puedes editar tu publicación? Hay una coma adicional en ''Varchar (50)'),'. No puedo editar porque es solo 1 símbolo. – new2ios

+0

@ new2ios: hecho - gracias por señalarlo –

5

todavía podría haber una necesidad de consultar sub-elementos que la respuesta a esta pregunta no resolvería. Puede usar sql: variable para satisfacer el requisito de nodos() de un argumento literal de cadena para consultar elementos secundarios de un nodo específico de forma iterativa.

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) 
Cuestiones relacionadas