3

I have a XML variable in a stored procedure (SQL Server 2008), its sample value is

<parent_node>
   <category>Low</category>
   <category>Medium</category>
   <category>High</category>
</parent_node>

I have to take each category and insert into table as a separate record. How to iterate in XML and take individual node value?

If I want to call a stored procedure and send each category as input parameter, how we can do that? The stored procedure is legacy one, which accept only one category at at time. I am trying to do invoke procedure in this way.

  1. loop fetch single category from xml variable.
  2. invoke stored procedure with current category.
  3. move to next category.
  4. loop until list contain value.

Any help will be appreciated.

4

2 回答 2

5

Something like this?

DECLARE @XmlVariable XML = '<parent_node>
                              <category>Low</category>
                              <category>Medium</category>
                              <category>High</category>
                            </parent_node>'

INSERT INTO dbo.YourTargetTable(CategoryColumn)
  SELECT 
     XTbl.Cats.value('.', 'varchar(50)')
  FROM 
     @XmlVariable.nodes('/parent_node/category') AS XTbl(Cats)

Update: if you must use the old legacy stored procedure and cannot change it (that would be my preferred way of doing this), then you would have to do the row-by-agonizing-row (RBAR) looping yourself, e.g. by using a table variable:

-- declare temporary work table
DECLARE @RbarTable TABLE (CategoryName VARCHAR(50))

-- insert values into temporary work table
INSERT INTO @RbarTable(CategoryName)
  SELECT 
     XTbl.Cats.value('.', 'varchar(50)')
  FROM 
     @XmlVariable.nodes('/parent_node/category') AS XTbl(Cats)

-- declare a single category
DECLARE @CategoryNameToBeInserted VARCHAR(50)

-- get the first category
SELECT TOP 1 @CategoryNameToBeInserted = CategoryName FROM @RbarTable

-- as long as we have data
WHILE @CategoryNameToBeInserted IS NOT NULL
BEGIN
    -- execute your stored procedure here.....    
    EXEC sp_executesql N'dbo.YourStoredProcedure @CategoryName', 
                       N'@CategoryName VARCHAR(50)', 
                       @CategoryName = @CategoryNameToBeInserted

    -- delete the category we just inserted from the temporary work table
    DELETE FROM @RbarTable WHERE CategoryName = @CategoryNameToBeInserted

    -- see if we still have more categories to insert    
    SET @CategoryNameToBeInserted = NULL
    SELECT TOP 1 @CategoryNameToBeInserted = CategoryName FROM @RbarTable ORDER BY CategoryName
END
于 2013-05-11T16:23:49.943 回答
0

With XML in SQL Server there's always more than one way to do it. Depending on the size of your XML doc and the number of times you're querying it, you could be best off using sp_xml_preparedocument which parses the document, gives you a handle to reference it, and then you can query it as many times and ways as you want to. Here's how you do that:

declare @xml xml = '
<parent_node>
   <category>Low</category>
   <category>Medium</category>
   <category>High</category>
</parent_node>'
declare @xml_handle int

exec sp_xml_preparedocument @xml_handle output, @xml

select value from openxml(@xml_handle, '/parent_node/category', 2) with (value varchar(100) 'text()') x

exec sp_xml_removedocument @xml_handle
于 2013-05-11T16:28:52.457 回答