1

I have a table with a column ID and a column XMLData. Unfortunately, the XML data column does not currently have any reference to the ID inside the XML itself, so if I export this column only and parse it, I would not be able to tie it back to the ID.

I am trying to added a node to the XML similar to below:

<AddedNode>
    <Id>10862832</Id>
</AddedNode>

Which would allow for the ID to be parsed from the XML itself, and be connected back. I tried adding the data via the below method:

With Test_CTE (Id, XMLData, AddedXML)
As
(
select Id, XMLData, cast('<AddedNode>
            <Id>' + cast(Id as varchar(20)) + '</Id>
        </AddedNode>' as varchar(max)) as AddedXML
from dbo.TestTable
)


update T
set XMLData.modify('insert ' + CTE.AddedXML + '
        as last into (/RootNode[1])
') 
from dbo.TestTable T
inner join Test_CTE CTE on CTE.Id = T.Id

But I receive the error "The argument 1 of the XML data type method "modify" must be a string literal."

I'm sure this has to do with me trying to pull the insert node via a column of data, but could anyone tell me how to fix it?

NOTE: I realize that I could also complete this via a while loop over entire table using variables, but there are ~2.5 million rows in the table and it would take longer than I want.

1 Answer 1

1

If I get this correctly, this can be done much easier:

DECLARE @testtable TABLE(ID INT IDENTITY, XMLData XML);
INSERT INTO @testtable VALUES('<root><a>test</a></root>')
                            ,('<root><a>test</a><b>Some other</b></root>');

UPDATE @testtable SET XMLData.modify(N'insert <AddedNode><Id>{sql:column("ID")}</Id></AddedNode> as first into (/root)[1]');

SELECT * FROM @testtable;

The result

ID  XMLData
1   <root>
      <AddedNode>
        <Id>1</Id>
      </AddedNode>
      <a>test</a>
    </root>

2   <root>
      <AddedNode>
        <Id>2</Id>
      </AddedNode>
      <a>test</a>
      <b>Some other</b>
    </root>

UPDATE

Your own approach might be corrected to this (never build XML via string concatenation!):

WITH Test_CTE AS
(
    SELECT XMLData
         ,(SELECT ID AS [Id] FOR XML PATH('AddedNode'),TYPE)  as AddedXML
    FROM dbo.TestTable
)
UPDATE Test_CTE SET XMLData.modify(N'insert sql:column("AddedXML") as first into (/root)[1]');

SELECT * FROM dbo.TestTable;
Sign up to request clarification or add additional context in comments.

2 Comments

Well that was too easy. Thanks for the quick response. I will accept as soon as it opens up.
@rdbradshaw Just to show you, where you went wrong, I placed an update how to correct your own attempt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.