replace value of (XML DML)

適用於:SQL ServerAzure SQL DatabaseAzure SQL 受控執行個體

更新文件中的節點值。

Syntax

replace value of Expression1   
with Expression2  

注意

若要檢視 SQL Server 2014 (12.x) 和舊版的 Transact-SQL 語法,請參閱 舊版檔

引數

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)。 接著便從 ProductModel 資料表的 Instructions 資料行,將製造指示 XML 執行個體複製成 T 資料表,然後套用插入至 T 資料表中的 XML。

USE AdventureWorks2022;
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 資料修改語言 (XML DML)