SQL Server 2005 大幅增強 FOR XML 功能:引入 TYPE 指令支援 xml 資料型別回傳、支援巢狀 FOR XML 查詢構建複雜階層、WITH XMLNAMESPACES 管理命名空間、全新 PATH 模式以屬性路徑方式靈活定義 XML 結構。本文以 AdventureWorks 範例資料庫為基礎,完整示範進階用法。
-- 無 TYPE:回傳 nvarchar(max),SSMS 無法點擊檢視 XML 結構
DECLARE @str NVARCHAR(1024);
SET @str = (SELECT ProductID, [Name] FROM Production.Product
WHERE ProductSubcategoryID = 9 FOR XML AUTO);
SELECT @str; -- 純文字
-- 有 TYPE:回傳 xml 型別,支援 xml 方法、索引、SSMS 視覺化
DECLARE @x XML;
SET @x = (SELECT ProductID, [Name] FROM Production.Product
WHERE ProductSubcategoryID = 9 FOR XML AUTO, TYPE);
SELECT @x; -- 可點擊展開 XML 樹狀結構
關鍵差異:TYPE 讓 FOR XML 結果可直接賦值給 xml 變數/欄位,進而使用 .query()、.value()、.exist()、.nodes() 等 XML 方法,並支援 XML 索引。
SELECT ProductSubcategoryID, [Name],
(SELECT ProductID, [Name]
FROM Production.Product AS Product
WHERE ProductSubcategoryID = 9
FOR XML AUTO, TYPE) AS Products
FROM Production.ProductSubcategory AS Category
WHERE ProductSubcategoryID = 9
FOR XML AUTO;
輸出:
<Category ProductSubcategoryID="9" Name="Derailleurs">
<Products>
<Product ProductID="894" Name="Rear Derailleur" />
<Product ProductID="945" Name="Front Derailleur" />
</Products>
</Category>
關鍵規則:子查詢 必須加 TYPE,否則子查詢結果會被編碼為屬性值字串 (<Product ...>),喪失結構。
WITH XMLNAMESPACES ('uri0' AS ns0)
SELECT ProductSubcategoryID, [Name],
(SELECT ProductID, [Name]
FROM Production.Product AS Product
WHERE ProductSubcategoryID = 9
FOR XML RAW('ns0:Product'), TYPE) AS 'ns0:Products'
FROM Production.ProductSubcategory AS Category
WHERE ProductSubcategoryID = 9
FOR XML RAW('ns0:Category'), ROOT('ns0:Message');
WITH XMLNAMESPACES (DEFAULT 'https://blog.csdn.net/zhzuo')
SELECT ProductSubcategoryID, [Name],
(SELECT ProductID, [Name]
FROM Production.Product AS Product
WHERE ProductSubcategoryID = 9
FOR XML AUTO, TYPE) AS Products
FROM Production.ProductSubcategory AS Category
WHERE ProductSubcategoryID = 9
FOR XML AUTO, ROOT('Message');
比 EXPLICIT 簡單得多,比 AUTO/RAW 靈活得多。
WITH XMLNAMESPACES (DEFAULT 'https://blog.csdn.net/zhzuo')
SELECT ProductID AS 'Product/@ProductID',
[Name] AS 'Product/Name'
FROM Production.Product
WHERE ProductSubcategoryID = 9
FOR XML PATH(''), ROOT('Products');
輸出:
<Products xmlns="https://blog.csdn.net/zhzuo">
<Product ProductID="894">
<Name>Rear Derailleur</Name>
</Product>
<Product ProductID="945">
<Name>Front Derailleur</Name>
</Product>
</Products>
語法規則:
— 別名 @AttrName → 屬性
— 別名 ElementName → 子元素
— 別名 Parent/Child/@Attr → 巢狀結構
— PATH('') 移除預設 <row> 包裹元素
— ROOT('RootName') 加根元素
SqlCommand.ExecuteXmlReader() 直接取得 XmlReader,無需字串轉換,效能最佳。xml 型別,配合強型別 Schema,減少 Map 複雜度。FOR JSON PATH 2016+),或輸出 XML 回應。| 功能 | SQL 2005 | SQL 2008+ | SQL 2016+ |
|---|---|---|---|
| TYPE 指令 | ✓ | ✓ | ✓ |
| 巢狀 FOR XML | ✓ | ✓ | ✓ |
| WITH XMLNAMESPACES | ✓ | ✓ | ✓ |
| PATH 模式 | ✓ | ✓ | ✓ |
| FOR JSON | ✗ | ✗ | ✓ (PATH/AUTO) |
掌握 FOR XML 進階功能,能在資料庫層直接產出符合業務合約的 XML/JSON 結構,減少中介層轉換邏輯,提升端到端效能與可維護性。