0

我需要使用 TSQL 变量的内容更新 XML 元素中的值。增加的复杂性是可以有多个具有相同名称的元素,并且所有元素都需要更新。这是一个示例。请注意,客户 1000000 有两个 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 中的多个值是不可能的。

您可以在 while 循环中执行此操作,该循环迭代您在一个 XML 中拥有的名字的数量。

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 进行重复数据删除?如果您将所有值设置为相同的值,那么存储第二个名称确实没有意义。您可以根据他们的位置删除第二个 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 回答