I have a table in SQL Server 2012 with this structure:
CREATE TABLE [dbo].[tblStepList]
(
[ToDoId] [int] IDENTITY(1,1) NOT NULL,
[Data] [xml] NOT NULL
)
And the Data
column is of type XML
and contents like this:
<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
</Step>
</Steplist>'
I want to update each row of the table with my new xml to look with new node named TextReadingId after TextReading name
I have a secondary table with text reading values stepid and textreadingid
StepId TextReadingId
---------------------------------------------------
e36a3450-1c8f-44da-b4d0-58e5bfe2a987 118
4078c1b1-71ea-4578-ba61-d2f6a5126ba1 119
d466a8ee-9214-4b9c-94f9-2117f5dffe93 401
And I want my TextReadingId values to come from the table above
<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
<TextReadingId>118</TextReadingId>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
<TextReadingId>401</TextReadingId>
</Step>
</Steplist>';
This is what I tried but it is not working as expected
DECLARE @i int;
SELECT
@i = s.data.value('count(/Steplist/Step)', 'nvarchar(max)')
FROM
tblStepList s
SET data.modify('insert <TextReadingId>{sql:variable("@i")}</TextReadingId> as last into (/Steplist/Step[sql:variable("@i")])[1]')
PRINT @i
Here is another answer that helped but it does not join with my other table for the results
The easiest way to do this is to rebuild each Step
node and then aggregate it back up using FOR XML
Within the correlated subquery, we do the following:
Step
nodes using .nodes()
StepReading
on the StepId
node valueStep
node..../*
...TextReadingId
with the value from StepReading
FOR XML
UPDATE sl
SET Data = (
SELECT v.Step.query('
<Step>{./*,
if (not(./TextReadingId)) then
<TextReadingId>{sql:column("sr.TextReadingId")}</TextReadingId>
else ()
}
</Step>
')
FROM sl.Data.nodes('/Steplist/Step') v(Step)
LEFT JOIN StepReading sr ON sr.StepId = v.Step.value('(StepId/text())[1]','uniqueidentifier')
FOR XML PATH(''), ROOT('Steplist'), TYPE
)
FROM tblStepList sl;