Search code examples
sql-server-2005sqlxml

SQL server insert data from table into an XML variable


How can I insert a whole bunch of rows into an XML variable without using a cursor? I know I can do

SET @errors.modify('insert <error>{ sql:variable("@text") }</error> as last into /errors[1]')

to insert the value of a variable, but I want to basically do

SET @errors.modify(SELECT 'insert <error>{ sql:column("text") }</error>' FROM table)

which, of course, isn't legal syntax.

Edit: Obviously my question wasn't clear. What I want is to be able to do like this:

CREATE TABLE my_table(text nvarchar(50))
INSERT INTO my_table VALUES('Message 2')
INSERT INTO my_table VALUES('Message 3')

DECLARE @errors xml
SET @errors = '<errors><error>Message 1</error></errors>'

SET @errors.modify('INSERT EVERYTHING FROM my_table MAGIC STATEMENT')

And after running this code, @errors should contain

<errors>
  <error>Message 1</error>
  <error>Message 2</error>
  <error>Message 3</error>
</errors>

Solution

  • Based on marc's answer, here is a solution that works for SQL Server 2005:

    CREATE TABLE #my_table(text nvarchar(50))
    INSERT INTO #my_table VALUES('Message 2')
    INSERT INTO #my_table VALUES('Message 3')
    
    DECLARE @errors xml
    SET @errors = '<errors><error>Message 1</error></errors>'
    
    SELECT @errors = CAST(@errors AS nvarchar(max)) + '<new>' + (SELECT text AS 'error' FROM #my_table FOR XML PATH(''), ELEMENTS) + '</new>'
    
    SET @errors = CAST(@errors AS nvarchar(max)) + '<new>' + @newErrors + '</new>'
    SET @errors.modify('insert (/new/*) as last into (/errors)[1]')
    SET @errors.modify('delete (/new)')
    
    SELECT @errors
    
    DROP TABLE #my_table
    

    Will return

    <errors>
      <error>Message 1</error>
      <error>Message 2</error>
      <error>Message 3</error>
    </errors>