產生 XML 執行個體

XML 資料類型中所述,您可以在 SQL Server 資料庫中儲存 XML 執行個體。這個主題描述如何產生 XML 執行個體。

在 SQL Server 中,您可以用下列方式產生 XML 執行個體:

  • 類型轉換字串執行個體。

  • 使用含有 FOR XML 子句的 SELECT 陳述式。

  • 使用常數指派。

  • 使用大量載入。

類型轉換字串和二進位執行個體

您可以將字串轉換 (CAST 或 CONVERT) 為 xml 資料類型,以便將任何 SQL Server 字串資料類型 (例如 [n][var]char[n]textvarbinaryimage) 轉換成 xml 資料類型。將會檢查不具類型的 XML 以確認它的格式正確。如果有與 xml 類型關聯的結構描述,也會執行驗證。如需詳細資訊,請參閱<比較不具類型的 XML 與具類型的 XML>。

XML 文件可以使用不同的編碼 (例如,UTF-8、UTF-16、windows-1252) 加以編碼。以下是字串與二進位來源類型如何與 XML 文件編碼互動以及剖析器作用方式的規則。

由於 nvarchar 假設使用兩個位元組的 Unicode 編碼 (例如 UTF-16 或 UCS-2),因此 XML 剖析器會將字串值視為兩個位元組的 Unicode 編碼 XML 文件或片段。這表示必須將 XML 文件以兩個位元組的 Unicode 編碼加以編碼,才能與來源資料類型相容。雖然 UTF-16 編碼的 XML 文件可有 UTF-16 位元組順序標示 (BOM),但它並不需要,因為來源類型的內容已經清楚表示,它只能為兩個位元組的 Unicode 編碼文件。

XML 剖析器會將 varchar 字串的內容視為一個位元組編碼的 XML 文件/片段。由於 varchar 來源字串有關聯的字碼頁,當 XML 本身未明確指定編碼時,剖析器將使用該字碼頁進行編碼。如果 XML 執行個體具有 BOM 編碼宣告,此 BOM 或宣告必須與字碼頁一致,否則剖析器將會報告錯誤。

varbinary 的內容會被視為是直接傳送至 XML 剖析器的字碼指標資料流。因此,XML 文件或片段必須以內嵌方式提供 BOM 或其他編碼資訊。剖析器只會查看資料流來決定編碼。這表示 UTF-16 編碼的 XML 必須提供 UTF-16 BOM,不具有 BOM 和宣告編碼的執行個體將被解譯為 UTF-8。

如果預先不知道 XML 文件的編碼,且在轉換成 XML 之前,將資料傳送為字串或二進位資料而非 XML 資料,則建議將資料視為 varbinary。例如,使用 OpenRowset() 讀取 XML 檔案的資料時,必須將要讀取的資料指定為 varbinary(max) 值:

select CAST(x as XML) 
from OpenRowset(BULK 'filename.xml', SINGLE_BLOB) R(x)

SQL Server 會在內部以 UTF-16 編碼之有效率的二進位表示法來表示 XML。不會保留使用者提供的編碼,但是會在剖析過程中考慮該編碼。

類型轉換 CLR 使用者定義型別

如果 CLR 使用者定義型別具有 XML 序列化,即可將該類型的執行個體明確轉換成 XML 資料類型。如需有關 CLR 使用者定義型別之 XML 序列化的詳細資訊,請參閱<從 CLR 資料庫物件進行 XML 序列化>。

以具類型的 XML 處理空白

在 SQL Server 中,元素內容中的空白如果發生在以標記 (如開始或結束標記) 所分隔的僅空白字元資料序列內且未實體化,則會將它視為無意義。(將會忽略 CDATA 區段。)空白處理的方式與 XML 1.0 規格 (由全球資訊網協會 (W3C) 所發佈) 所述的空白處理方式不同。這是因為 SQL Server 中的 XML 剖析器,只能辨識有限的 DTD 子集數目,如 XML 1.0 中所定義。如需有關 SQL Server 中所支援之有限 DTD 子集的詳細資訊,請參閱<CAST 和 CONVERT (Transact-SQL)>。

依預設,只要下列任一項為真,當 XML 剖析器將字串資料轉換成 XML 時,將會捨棄無意義的空白。

  • 未在元素或其上階元素定義 The xml:space 屬性。

  • 在某個元素或在其中一個它的上階元素生效的 xml:space 屬性,具有預設值。

例如:

declare @x xml
set @x = '<root>      <child/>     </root>'
select @x 

以下是結果:

<root><child/></root>

然而,您可以變更此行為。若要保留 xml DT 執行個體的空白,請使用 CONVERT 運算子並將其選擇性的 style 參數設定成 1 的值。例如:

SELECT CONVERT(xml, N'<root>      <child/>     </root>', 1)

如果未使用 style 參數或是將其值設為 0,在轉換 xml DT 執行個體時,將不會保留不重要的空白。如需如何使用 CONVERT 運算子以及將字串資料轉換成 xmlDT 執行個體時它的 style 參數之詳細資訊,請參閱<CAST 和 CONVERT (Transact-SQL)>。

範例:將字串值轉換成具類型的 xml 並將它指派給資料行

下列範例將含有 XML 片段的字串變數轉換成 xml 資料類型,然後在 xml 類型資料行中儲存它:

CREATE TABLE T(c1 int primary key, c2 xml)
go
DECLARE  @s varchar(100)
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 

下列插入作業會將字串隱含轉換成 xml 類型:

INSERT INTO T VALUES (3, @s) 

您可以明確地使用 cast() 將字串轉換成 xml 類型:

INSERT INTO T VALUES (3, cast (@s as xml))

或者您可以使用 convert(),如下列所示:

INSERT INTO T VALUES (3, convert (xml, @s)) 

範例:將字串轉換成具類型的 xml 並將它指派給變數

在下列範例中,會將字串轉換成 xml 類型,並將它指派給 xml 的變數。

declare @x xml
declare  @s varchar(100)
SET @s = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 
set @x =convert (xml, @s)
select @x

使用含有 FOR XML 子句的 SELECT 陳述式

您可以在 SELECT 陳述式中使用 FOR XML 子句以傳回 XML 的結果。例如:

DECLARE @xmlDoc xml
SET @xmlDoc = (SELECT Column1, Column2
               FROM   Table1, Table2
               WHERE   Some condition
               FOR XML AUTO)
 ...

SELECT 陳述式會傳回文字 XML 片段,該片段會在指派期間剖析成 xml 資料類型變數。

您也可以在 FOR XML 子句中使用 TYPE 指示詞,該子句會直接以 xml 類型傳回 FOR XML 查詢結果:

Declare @xmlDoc xml
SET @xmlDoc = (SELECT ProductModelID, Name
               FROM   Production.ProductModel
               WHERE  ProductModelID=19
               FOR XML AUTO, TYPE)
SELECT @xmlDoc

以下是結果:

<Production.ProductModel ProductModelID="19" Name="Mountain-100" />...

在下列範例中,會將 FOR XML 查詢之具類型的 xml 結果插入 xml 類型資料行:

CREATE TABLE T1 (c1 int, c2 xml)
go
INSERT T1(c1, c2)
SELECT 1, (SELECT ProductModelID, Name
           FROM Production.ProductModel
           WHERE ProductModelID=19
           FOR XML AUTO, TYPE)
SELECT * FROM T1
go

如需 FOR XML 的詳細資訊,請參閱<使用 FOR XML 建構 XML>。

[!附註]

SQL Server 會將 xml 資料類型執行個體傳回用戶端,作為不同伺服器建構的結果 (例如使用 TYPE 指示詞的 FOR XML 查詢),或者使用 xml 資料類型從 SQL 資料行、變數和輸出參數傳回 XML。在用戶端應用程式的程式碼中,ADO.NET 提供者會要求從伺服器以二進位編碼傳送這項 xml 資料類型資訊。但若您使用的 FOR XML 不含 TYPE 指示詞,XML 資料就會以字串類型傳回。在任一情況下,用戶端提供者將永遠可以處理任一 XML 形式。

使用常數指派

在應有 xml 資料類型的執行個體中可以使用字串常數。這與使用 CAST 將字串隱含轉換成 XML 是相同的。例如:

DECLARE @xmlDoc xml
SET @xmlDoc = '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>' 
-- Or
SET @xmlDoc = N'<?xml version="1.0" encoding="ucs-2"?><doc/>'

在上述範例中,會將字串隱含轉換成 xml 資料類型,並將它指派給 xml 類型變數。

下列範例會將常數字串插入 xml 類型資料行:

CREATE TABLE T(c1 int primary key, c2 xml)
INSERT INTO T VALUES (3, '<Cust><Fname>Andrew</Fname><Lname>Fuller</Lname></Cust>') 

[!附註]

對於具類型的 XML,將會針對指定的結構描述驗證 XML。如需詳細資訊,請參閱<比較不具類型的 XML 與具類型的 XML>。

使用大量載入

增強的 OPENROWSET (Transact-SQL) 功能,可讓您在資料庫中大量載入 XML 文件。您可以從檔案將 XML 執行個體大量載入資料庫中的 xml 類型資料行。如需實用範例,請參閱<大量匯入和匯出 XML 文件的範例>。如需有關載入 XML 文件的詳細資訊,請參閱<載入 XML 資料>。

本章節內容

主題

描述

擷取 XML 資料

描述當 XML 執行個體儲存於資料庫中時,未保留的 XML 執行個體部分。