Как обновить существующее значение узла XML, умножив его на n раз в SQL Server

Вот XML у меня в поле таблицы

<CtcConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Ctc>3</Ctc>
    <SalaryComponent>
        <SalaryComponentConfiguration>
            <Name>Basic</Name>
            <DisplayOrder>0</DisplayOrder>
            <Value>5634655</Value>
        </SalaryComponentConfiguration>
        <SalaryComponentConfiguration>
            <Name>HR</Name>
            <DisplayOrder>0</DisplayOrder>
            <Value>1234</Value>
        </SalaryComponentConfiguration>
        <SalaryComponentConfiguration>
            <Name>medical</Name>
            <DisplayOrder>0</DisplayOrder>
            <Value>0</Value>
        </SalaryComponentConfiguration>
    </SalaryComponent>
</CtcConfiguration>

Я хочу обновить существующее node(DisplayOrder) значение путем умножения его на п раз.

Это то, что я до сих пор получаю, чтобы обновить значение узла:

    DECLARE @NodeName VARCHAR(100)=N'Basic';
    DECLARE @NewValue INT=3;
    UPDATE payroll.pays 
    SET CtcConfiguration.modify(
          N'replace value of (/CtcConfiguration
                              /SalaryComponent
                              /SalaryComponentConfiguration[(Name/text())[1]=sql:variable("@NodeName")]
                              /Value/text())[1] 
            with sql:variable("@NewValue")');

1 ответ

Решение

Я хочу предложить вам два подхода:

Используйте эти переменные, чтобы выбрать правильный узел и определить множитель

DECLARE @AttributeName VARCHAR(100)=N'medical';
DECLARE @Multiply INT=2;

UPDATE YourTable
SET YourXML.modify(N'replace value of (/CtcConfiguration
                                       /SalaryComponent
                                       /SalaryComponentConfiguration[(Name/text())[1]=sql:variable("@AttributeName")]
                                       /DisplayOrder/text())[1] 
                     with xs:int((/CtcConfiguration
                                 /SalaryComponent
                                 /SalaryComponentConfiguration[(Name/text())[1]=sql:variable("@AttributeName")]
                                 /DisplayOrder/text())[1]) * sql:variable("@Multiply")');

- В качестве альтернативы вы можете использовать обновляемый CTE:
- В этом случае вы используете sql:column() вместо sql:variable()

SET @AttributeName=N'Basic';

WITH cte AS
(
    SELECT *
           --you can place any multiplier here
          ,10 * YourXML.value(N'(/CtcConfiguration
                                 /SalaryComponent
                                 /SalaryComponentConfiguration[(Name/text())[1]=sql:variable("@AttributeName")]
                                 /DisplayOrder/text())[1] ',N'int') AS NewValue
    FROM YourTable
)
UPDATE cte
SET YourXML.modify(N'replace value of (/CtcConfiguration
                                       /SalaryComponent
                                       /SalaryComponentConfiguration[(Name/text())[1]=sql:variable("@AttributeName")]
                                       /DisplayOrder/text())[1] 
                     with sql:column("NewValue")');
Другие вопросы по тегам