I want to update multiple XML nodes in single Update query
XML:
<TransmissionData> <HolderName>Tony Chase</CardHolderName> <Type>VS</CardType> <TransactionDetails> <TransactionId /> </TransactionDetails> <ValueType>CAPT</ValueType> </TransmissionData>
This is what I have tried:
DECLARE @Type nVarchar(10) = 'MS' DECLARE @ValueType nVarchar(10) = 'OPT' DECLARE @TransactionId bigint = 122344555 UPDATE Table1 SET Data.modify('replace value of (/TransmissionData/CardType/text())[1] with sql:variable("@Type")'), Data.modify('replace value of (/TransmissionData/ValueType/text())[2] with sql:variable("@ValueType")'), Data.modify('replace value of (/TransmissionData/TransactionDetails/TransactionId/text())[1] with sql:variable("@TransactionId")') WHERE RequestId = 2133831593
It works only for single Update, if I use more then one like ValueType and TransactionId, it shows an error. Please help me – how to update this?
Msg 264, Level 16, State 1, Line 7
The column name ‘TransmissionData’ is specified more than once in the SET clause or column list of an INSERT. A column cannot be assigned more than one value in the same clause. Modify the clause to make sure that a column is updated only once. If this statement updates or inserts columns into a view, column aliasing can conceal the duplication in your code.
Advertisement
Answer
Please try the following solution.
It is using XQuery and its FLWOR expression.
It will update XML elements in question, leaving everything else intact.
I had to fix the input XML to make it well-formed.
SQL
-- DDL and sample data population, start DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML); INSERT INTO @tbl (xmldata) VALUES (N'<TransmissionData> <CardHolderName>Tony Chase</CardHolderName> <CardType>VS</CardType> <TransactionDetails> <TransactionId /> </TransactionDetails> <ValueType>CAPT</ValueType> </TransmissionData>'); -- DDL and sample data population, end DECLARE @Type NVARCHAR(10) = 'MS' , @ValueType NVARCHAR(10) = 'OPT' , @TransactionId BIGINT = 122344555; UPDATE @tbl SET xmldata = xmldata.query('<TransmissionData> { for $x in /TransmissionData/* return if (local-name($x)="CardType") then <CardType>{sql:variable("@Type")}</CardType> else if (local-name($x)="ValueType") then <ValueType>{sql:variable("@ValueType")}</ValueType> else if (local-name($x)="TransactionDetails") then <TransactionDetails> <TransactionId>{sql:variable("@TransactionId")}</TransactionId> </TransactionDetails> else $x } </TransmissionData>'); -- test SELECT * FROM @tbl;