SQL Server 2005 引入 xml 型別與 xml.modify() 方法,支援三種 XML DML 操作:insert、delete、replace value of。本文以完整範例 XML 文件為基礎,系統展示節點插入 (位置控制、多節點、屬性、文字、註解、處理指令、條件插入)、刪除 (屬性、節點、文字、整棵子樹)、取代 (屬性值、文字值、條件取代) 的完整語法與結果。
DECLARE @XMLVar XML = '
Windows Step By Step
Bill Zack
49.99
Developing ADO .NET
Andrew Brust
39.93
Windows Cluster Server
Stephen Forte
59.99
';
-- 作為第一個子節點插入
SET @XMLVar.modify('insert as first into (/catalog[1]/book[1])');
-- 作為最後一個子節點插入
SET @XMLVar.modify('insert as last into (/catalog[1]/book[1])');
-- 在 author 前插入
SET @XMLVar.modify('insert before (/catalog[1]/book[1]/author[1])');
-- 在 author 後插入
SET @XMLVar.modify('insert after (/catalog[1]/book[1]/author[1])');
SELECT @XMLVar.query('/catalog[1]/book[1]');
結果: first、before、author、after、price、last 依序排列
-- 方法 1:變數
DECLARE @newFeatures XML = 'one element second element ';
SET @XMLVar.modify('insert sql:variable("@newFeatures") into (/catalog[1]/book[1])');
-- 方法 2:直接序列
SET @XMLVar.modify('insert (one element ,second element ) into (/catalog[1]/book[1]/author[1])');
-- 變數插入屬性
DECLARE @var NVARCHAR(10) = N'變數插入';
SET @XMLVar.modify('insert (attribute var {sql:variable("@var")}) into (/catalog[1]/book[1])');
-- 直接插入屬性
SET @XMLVar.modify('insert (attribute name {"直接插入"}) into (/catalog[1]/book[1]/title[1])');
-- 多屬性一次插入
SET @XMLVar.modify('insert (attribute Id {"多值插入1"}, attribute name {"多值插入2"}) into (/catalog[1]/book[1]/author[1])');
SET @XMLVar.modify('insert text{"at first"} as first into (/catalog[1]/book[1])');
-- 同樣支援 as last / before / after
SET @XMLVar.modify('insert before (/catalog[1]/book[1]/title[1])');
SET @XMLVar.modify('insert before (/catalog[1]/book[1]/title[1])');
SET @XMLVar.modify('
insert
if (/catalog[1]/book[1]/title[2]) then
text{"this is a 1 step"}
else
text{"this is a 2 step"}
into (/catalog[1]/book[1]/price[1])');
-- 因 title[2] 不存在,插入 "this is a 2 step"
-- 刪除屬性
SET @XMLVar.modify('delete /catalog[1]/book[1]/@category');
-- 刪除節點 (含子樹)
SET @XMLVar.modify('delete /catalog[1]/book[1]/title[1]');
-- 刪除文字內容 (保留元素)
SET @XMLVar.modify('delete /catalog[1]/book[1]/author[1]/text()');
-- 刪除整個 book[2] 元素
SET @XMLVar.modify('delete /catalog[1]/book[2]');
SELECT @XMLVar.query('/catalog[1]');
結果: book[1] 僅剩 <book><author/><price>49.99</price></book>,book[2] 整個移除,book[3] 保留
-- 取代屬性值
SET @XMLVar.modify('replace value of (/catalog[1]/book[1]/@category) with ("取代屬性")');
-- 取代文字節點值
SET @XMLVar.modify('replace value of (/catalog[1]/book[1]/author[1]/text()[1]) with ("取代內容")');
-- 條件取代
SET @XMLVar.modify('replace value of (/catalog[1]/book[2]/@category) with (
if (count(/catalog[1]/book) > 4) then "條件取代1" else "條件取代2"
)');
-- 因 book 共 3 筆,取代為 "條件取代2"
SELECT @XMLVar.query('/catalog[1]');
| 操作 | 語法模板 | 關鍵字 |
|---|---|---|
| 插入元素 | insert <elem/> {as first|as last|before|after} into/after/before (XPath) | as first/last, before/after |
| 插入屬性 | insert (attribute name {expr}) into (XPath) | attribute |
| 插入文字 | insert text{expr} {as first|as last|before|after} into/after/before (XPath) | text{} |
| 插入註解 | insert <!--comment--> {before|after} (XPath) | |
| 插入處理指令 | insert <?target data?> {before|after} (XPath) | ?> |
| 刪除 | delete XPath | delete |
| 取代值 | replace value of XPath with expr | replace value of |
| 條件邏輯 | if (cond) then expr1 else expr2 | if/then/else |
| SQL 變數引用 | sql:variable("@var") 或 sql:column("table.col") | sql:variable/column |
xml.modify() 會觸發 XML 索引維護,大量批次修改建議:TRY...CATCH 確保交易一致性