分享方式:


replace value of (XML DML)

適用於:SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體

更新文件中的節點值。

語法

replace value of Expression1
with Expression2

引數

Expression1

識別要更新的值節點。 它必須只識別一個節點。 也就是說,Expression1 必須是靜態單一的。 如果輸入 XML,節點的類型必須是 簡單類型。 如果選取多個節點,就會引發錯誤。 如果 Expression1 傳回空的序列,將不會發生值取代,而且也不會傳回錯誤。 Expression1 必須傳回單一項目,其具有簡單類型的內容 (清單或不可部分完成類型)、文字節點或屬性節點。 Expression1 不能是聯集類型、複雜類型、處理指示、文件節點或註解節點,否則會傳回錯誤。

Expression2

識別節點的新值。 它可以是傳回簡單類型節點的表達式,因為 data() 會隱含使用。 如果值是值清單, update 語句會將舊的值取代為清單。 當您修改具類型的 XML 實例時,Expression2 必須是相同類型或 Expression1子類型。 否則,就會傳回錯誤。 當您修改不具類型的 XML 實例時, Expression2 必須是可原子化的表達式。 否則,就會傳回錯誤。

範例

本文 Transact-SQL 程式碼範例使用 AdventureWorks2022AdventureWorksDW2022 範例資料庫,從 Microsoft SQL Server Samples 和 Community Projects (Microsoft SQL Server 範例和社群專案)首頁即可下載。

下列 XML DML 語句範例 replace value of 說明如何更新 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 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 數據行的AdventureWorks2022數據表 (T)。 接著,您會將製造指令 XML 實例從 Instructions 資料表中的數據 ProductModel 行複製到數據表 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="http://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="http://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="http://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值時使用castcast 當值必須是特定型別時,則需要 。 在此範例中,如果 500 為 值,則不需要明確轉換。