replace value of (XML DML)

ドキュメント内のノードの値を更新します。

構文

replace value of 
      Expression1 
with
      Expression2

引数

  • Expression1
    値を更新するノードを特定します。 この引数では、ノードを 1 つだけ特定します。 つまり、Expression1 には静的なシングルトンを指定する必要があります。 XML が型指定されている場合、ノードの型は単純型でなければなりません。 複数のノードを選択すると、エラーが発生します。 Expression1 が空のシーケンスを返す場合は、値の置換は行われず、エラーは返されません。 Expression1 からは、単純型に型指定された内容 (リストまたはアトミック型)、テキスト ノード、または属性ノードを持つ 1 つの要素が返される必要があります。 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 つだけにする必要があることに注意してください。パス式の末尾に "[1]" を追加して明示的に 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 列に格納されている製造手順ドキュメント内の値を置換します。

この例では、まず、型指定された XML 列を含むテーブル (T) を AdventureWorks データベースに作成します。 次に、製造手順の 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 DML (XML データ変更言語)

その他の技術情報

xml データ型のメソッド