替换 (XML DML) 的值

在文档中更新节点的值。

语法

replace value of 
      Expression1 
with
      Expression2

参数

  • Expression1
    标识其值要更新的节点。 它必须仅标识一个单个节点。 即 Expression1 必须是一个静态单独。 如果 XML 已类型化,则节点的类型必须是简单类型。 如果选择了多个节点,则会出现错误。 如果 Expression1 返回空序列,则不会发生值替换,也不会返回错误。 Expression1 必须返回具有简单类型内容(列表或原子类型)的单个元素、文本节点或属性节点。 Expression1 不可能是联合类型、复杂类型、处理指令、文档节点或注释节点。 如果它是,则会返回错误。

  • Expression2
    标识节点的新值。 这可能是返回简单类型节点的表达式,因为将隐式使用 data()。 如果该值是值列表,则 update 语句将使用此列表替换旧值。 在修改类型化的 XML 实例时,Expression2 必须是 Expression1 的相同类型或子类型。 否则,将返回错误。 在修改非类型化的 XML 实例中,Expression2 必须是可以进行原子化的表达式。 否则,将返回错误。

示例

replace value of XML DML 语句以下示例说明如何在 XML 文档中更新节点。

A.在 XML 实例中替换值

在以下示例中,首先将文档实例分配给 xml 类型的变量。 然后,replace value of XML DML 语句将更新文档中的值。

DECLARE @myDoc xml
SET @myDoc = '<Root>
<Location LocationID="10" 
            LaborHours="1.1"
            MachineHours=".2" >Manufacturing steps are described here.
<step>Manufacturing step 1 at this work center</step>
<step>Manufacturing step 2 at this work center</step>
</Location>
</Root>'
SELECT @myDoc

-- update text in the first manufacturing step
SET @myDoc.modify('
  replace value of (/Root/Location/step[1]/text())[1]
  with     "new text describing the manu step"
')
SELECT @myDoc
-- update attribute value
SET @myDoc.modify('
  replace value of (/Root/Location/@LaborHours)[1]
  with     "100.0"
')
SELECT @myDoc

请注意,更新的目标必须最多是一个通过在表达式的结尾添加“[1]”在路径表达式中显式指定的节点。

B.使用 if 表达式以确定替换值

可以在 replace value of XML DML 语句的 Expression2 中指定 if 表达式,如以下的示例所示。 Expression1 标识第一个生产车间的 LaborHours 属性将要更新。 Expression2 使用 if 表达式以确定 LaborHours 属性的新值。

DECLARE @myDoc xml
SET @myDoc = '<Root>
<Location LocationID="10" 
            LaborHours=".1"
            MachineHours=".2" >Manu steps are described here.
<step>Manufacturing step 1 at this work center</step>
<step>Manufacturing step 2 at this work center</step>
</Location>
</Root>'
--SELECT @myDoc

SET @myDoc.modify('
  replace value of (/Root/Location[1]/@LaborHours)[1]
  with (
       if (count(/Root/Location[1]/step) > 3) then
         "3.0"
       else
          "1.0"
      )
')
SELECT @myDoc

C.更新存储在非类型化的 XML 列中的 XML

以下示例更新存储在列中的 XML:

drop table T
go
CREATE TABLE T (i int, x xml)
go
INSERT INTO T VALUES(1,'<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>
  <Warranty>1 year parts and labor</Warranty>
  <Maintenance>3 year parts and labor extended maintenance is available</Maintenance>
</Features>
</ProductDescription>
</Root>')
go
-- verify the current <ProductDescription> element
SELECT x.query(' /Root/ProductDescription')
FROM T
-- update the ProductName attribute value
UPDATE T
SET x.modify('
  replace value of (/Root/ProductDescription/@ProductName)[1]
  with "New Road Bike" ')
-- verify the update
SELECT x.query(' /Root/ProductDescription')
FROM T

D.更新存储在类型化的 XML 列中的 XML

此示例替换存储在类型化的 XML 列中的生产说明文档中的值。

在该示例中,首先在 AdventureWorks 数据库中创建带有类型化的 XML 列的表 (T)。 然后将一个生产说明 XML 实例从 ProductModel 表的 Instructions 列复制到表 T 中。 随后再对表 T 中的 XML 内容应用插入操作。

use AdventureWorks
go
drop table T
go
create table T(ProductModelID int primary key, 
Instructions xml (Production.ManuInstructionsSchemaCollection))
go
insert  T 
select ProductModelID, Instructions
from Production.ProductModel
where ProductModelID=7
go
--insert a new ___location - <Location 1000/>. 
update T
set Instructions.modify('
  declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
insert <MI:Location LocationID="1000"  LaborHours="1000"  LotSize="1000" >
           <MI:step>Do something using <MI:tool>hammer</MI:tool></MI:step>
         </MI:Location>
  as first
  into   (/MI:root)[1]
')
go
select Instructions
from T
go
-- Now replace manu. tool in ___location 1000
update T
set Instructions.modify('
  declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
  replace value of (/MI:root/MI:Location/MI:step/MI:tool)[1] 
  with   "screwdriver"
')
go
select Instructions
from T
-- Now replace value of lot size
update T
set Instructions.modify('
  declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
  replace value of (/MI:root/MI:Location/@LotSize)[1] 
  with   500 cast as xs:decimal ?
')
go
select Instructions
from T

当替换 LotSize 值时请注意使用 cast。 当该值必须为特定类型时这是必需。 在此示例中,如果值为 500,则显式转换是不必要的。

请参阅

概念

类型化的 XML 与非类型化的 XML 的比较

创建 XML 数据的实例

XML 数据修改语言 (XML DML)

其他资源

XML 数据类型方法