0

XML 要素の値を TSQL 変数の内容で更新する必要があります。さらに複雑なのは、同じ名前の要素が複数存在する可能性があり、すべての要素を更新する必要があることです。これがサンプルです。顧客 1000000 には 2 つの customer_firstname 要素があることに注意してください。

CREATE TABLE Customer_Test
(
    [customer_data] [xml] NULL
) 

-- populate statements
insert into Customer_Test (customer_data) values ('<Customer Note="two customer_firstnames"><customer_id>1000000</customer_id><customer_firstname>Mary</customer_firstname><customer_firstname>Jane</customer_firstname><customer_lastname>Smith</customer_lastname></Customer>');
insert into Customer_Test (customer_data) values ('<Customer Note="normal, no problem"><customer_id>1000001</customer_id><customer_firstname>Joe</customer_firstname><customer_lastname>Bloggs</customer_lastname></Customer>');

以下のコードは、customer_ID = '1000001' レコードのように構造化された xml で問題なく機能しますが、customer_ID = '1000000' のような状況では、最初の customer_firstname 要素のみが更新されます。

DECLARE @newName varchar(10) = 'xxx'
DECLARE @IDValue varchar(10) = '1000000'
UPDATE  [Customer_Test] 
SET  customer_data.modify('replace value of (Customer/customer_firstname/text())[1] with sql:variable("@newName")') 
WHERE  customer_data.value('(/Customer/customer_id)[1]','varchar(50)') = @IDValue

私は本当にこれにこだわっています - customer_firstname 要素のすべての値が存在する場合は、同じ値に設定する必要があります。CROSS APPLY が必要だと半分疑っていますが、コードを作成しようとしてもコンパイルできませんでした。

提供される可能性のあるアドバイスを非常に高く評価します。前もって感謝します。

4

2 に答える 2

2

XML 内の複数の値を 1 つの update ステートメントで更新することはできません。

1 つの XML に含まれる名の数を反復する while ループで実行できます。

DECLARE @newName varchar(10) = 'xxx'
DECLARE @IDValue varchar(10) = '1000000'
DECLARE @FirstNameCount INT

-- Get the max number of first names in one XML
SELECT @FirstNameCount = max(customer_data.value('count(Customer/customer_firstname)', 'int'))
FROM Customer_Test
WHERE customer_data.value('(/Customer/customer_id)[1]','varchar(50)') = @IDValue

-- Loop over @FirstNameCoount
WHILE @FirstNameCount > 0
BEGIN
  UPDATE  [Customer_Test] 
  SET  customer_data.modify('replace value of (Customer/customer_firstname[sql:variable("@FirstNameCount")]/text())[1] with sql:variable("@newName")')
  WHERE  customer_data.value('(/Customer/customer_id)[1]','varchar(50)') = @IDValue

  SET @FirstNameCount = @FirstNameCount - 1
END
于 2012-08-31T11:54:18.350 に答える
0

この時点で XML を重複排除する価値はありませんか? すべての値を同じものに設定している場合、2 番目の名前を保存しても意味がありません。たとえば、位置に基づいて 2 番目の customer_firstname 要素を削除できます。

SELECT 'before' s, DATALENGTH( customer_data ) dl, [customer_data] FROM Customer_Test

UPDATE [Customer_Test]
SET  customer_data.modify('delete Customer/customer_firstname[position() > 1]')  

SELECT 'after 1' s, DATALENGTH( customer_data ) dl, [customer_data] FROM Customer_Test

DECLARE @newName varchar(10) = 'xxx' 
DECLARE @IDValue varchar(10) = '1000000' 
UPDATE [Customer_Test]
SET  customer_data.modify('replace value of (Customer/customer_firstname/text())[1] with sql:variable("@newName")')  
WHERE  customer_data.value('(/Customer/customer_id)[1]','varchar(50)') = @IDValue 

SELECT 'after 2' s, DATALENGTH( customer_data ) dl, [customer_data] FROM Customer_Test
于 2012-09-03T10:20:57.060 に答える