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 程式碼範例使用 AdventureWorks2022
或 AdventureWorksDW2022
範例資料庫,從 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
值時使用cast
。 cast
當值必須是特定型別時,則需要 。 在此範例中,如果 500
為 值,則不需要明確轉換。