Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I iterate through the Nodes of a XML Field in T-SQL?

Tags:

tsql

I have an XML field that I know will have at least one "ChildNode" in it, but possibly more. I am trying to make a loop in T-SQL that will get the XML of each ChildNode as a VarChar(1000) and do some logic with it. When I try the following...

...
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

I get the following error: The argument 1 of the xml data type method "value" must be a string literal.

I know that it's blowing up when I try to use the @intIterator in the value method as it wants a string literal instead of a variable, but then how can I iterate through the child nodes one by one in T-SQL?

like image 794
NoAlias Avatar asked Feb 15 '11 16:02

NoAlias


People also ask

How do I query values in XML nodes?

You can retrieve multiple values from the rowset. For example, you can apply the value() method to the rowset returned by nodes() and retrieve multiple values from the original XML instance. The value() method, when applied to the XML instance, returns only one value.

How do I select a specific XML node in SQL Server?

You should use the query() Method if you want to get a part of your XML. If you want the value from a specific node you should use value() Method. Update: If you want to shred your XML to multiple rows you use nodes() Method.

How do I filter XML data in SQL Server?

XQuery in the SQL Server helps to query and extract data from XML documents. XQuery gives different approaches to get information from the XML document and the equivalent can be used on applying a data filter or where clause on XML elements as well.

How can I get SQL query results in XML?

You can optionally retrieve formal results of a SQL query as XML by specifying the FOR XML clause in the query. The FOR XML clause can be used in top-level queries and in subqueries. The top-level FOR XML clause can be used only in the SELECT statement.


2 Answers

There still could be a need to query sub elements which the answer to this question would not solve. You can just use sql:variable to satisfy nodes() requirement of a string literal argument to query sub elements of a specific node iteratively.

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)
like image 101
frimley Avatar answered Jan 09 '23 18:01

frimley


I don't have any idea what your XML looks like, but you probably have to use a different approach - don't try to iterate and loop and stuff like that - instead use the .nodes() function in XQuery:

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

That basically leaves the iterating / looping to XQuery and you don't have to mess around with indices or anything like that at all.....

like image 39
marc_s Avatar answered Jan 09 '23 19:01

marc_s