Home > OS >  Update multiple XML nodes in single Update SQL statement
Update multiple XML nodes in single Update SQL statement

Time:10-14

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.

CodePudding user response:

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;
  • Related