共用方式為


使用 FOR XML 子句的規則

FOR XML 子句可以使用在最上層的查詢與子查詢中。最上層的 FOR XML 子句只能用在 SELECT 陳述式中。在子查詢中,FOR XML 可以在 INSERT、UPDATE 與 DELETE 陳述式中使用。它也可用在指派陳述式中。例如:

DECLARE @x xml
SET @x = (SELECT *
FROM Sales.Customer
FOR XML AUTO, TYPE)
SELECT @x

請注意,TYPE 指示詞會傳回 xml 類型的查詢結果。若未加入 TYPE 指示詞,就會以 nvarchar(max) 傳回 FOR XML 查詢結果。接著,此結果會轉換為 xml 並指派到 xml 類型的變數。

FOR XML 子句有下列幾項限制:

  • 對於任何使用 COMPUTE BY 或 FOR BROWSE 子句的選取作業,FOR XML 皆無效。例如,以下查詢將會產生錯誤:

    SELECT TOP 5 SalesOrderID, UnitPrice 
    FROM Sales.SalesOrderDetail 
    ORDER BY SalesOrderID COMPUTE SUM(UnitPrice) BY SalesOrderID
    FOR XML AUTO
    
  • 不含 TYPE 指示詞的最上層 FOR XML 無法與資料指標一起使用。

  • 當包含 FOR XML 子句的 SELECT 陳述式在查詢中指定四個部份的名稱時,若在本機電腦上執行查詢則伺服器名稱並不會隨著 XML 文件的結果傳回。但如果是在網路伺服器上執行查詢,則伺服器名稱是以四個部份的名稱而傳回。
    例如,請考量以下的查詢:

    SELECT TOP 1 LastName
    FROM ServerName.AdventureWorks.Person.Contact
    FOR XML AUTO
    

    ServerName 是本機伺服器,查詢將會傳回下列結果:

    <AdventureWorks.Person.Contact LastName="Achong" />
    

    ServerName 是網路伺服器,查詢將會傳回下列結果:

    <ServerName.AdventureWorks.Person.Contact LastName="Achong" />
    

    您可以指定下列別名來避免這種模稜兩可的情況:

    SELECT TOP 1 LastName
    FROM ServerName.AdventureWorks.Person.Contact x
    FOR XML AUTO 
    

    此查詢傳回的內容如下:

    <x LastName="Achong"/>
    

此外,若 SQL Server 名稱中含有對 XML 名稱而言無效的字元 (如空格),則會在轉譯為 XML 名稱時,將其無效字元轉譯為逸出的數值實體編碼。

XML 名稱中只允許兩種非字母字元:冒號 (:) 和底線 (_)。這是因為冒號已保留給命名空間,而底線已被選為逸出字元。以下是適用於編碼的逸出規則:

  • 根據 XML 1.0 規格,任何不屬於有效 XML 名稱字元的 UCS-2 字元,都會逸出為 _xHHHH_。HHHH 代表最高階位元優先順序之字元的四位數十六進位 UCS-2 碼。例如,資料表名稱 Order Details 就編碼為 Order_x0020_Details。

  • 不符合 UCS-2 範圍 (UCS-4 新增的,範圍介於 U+00010000 與 U+0010FFFF 之間) 的字元都會編碼為 _xHHHHHHHH_。在 SQL Server 2000 回溯相容性模式中,HHHHHHHH 代表字元的八位數十六進位 UCS-4 編碼。在其他情況下,字元會編碼為 _xHHHHHH_,以符合 SQL-2003 標準。

  • 除非下一個字元是 x,否則底線字元不需要逸出,例如資料表名稱 Order_Details 就未編碼。

  • 識別碼的冒號也不會逸出,因此命名空間元素及屬性名稱才能夠由 FOR XML 查詢產生。例如,下列查詢所產生的命名空間屬性在名稱中就有冒號:

    SELECT 'namespace-urn' as 'xmlns:namespace', 
     1 as 'namespace:a' 
    FOR XML RAW
    

    此查詢產生以下結果:

    <row xmlns:namespace="namespace-urn" namespace:a="1"/>
    

    請注意,建議使用 WITH XMLNAMESPACES 來加入 XML 命名空間。

  • 在 SELECT 查詢中,將任何資料行轉換為二進位大型物件 (BLOB),會使其成為遺失關聯資料表名稱與資料行名稱的暫存實體。而這會使得 AUTO 模式查詢產生錯誤,因為查詢不知道要將此值放入 XML 階層中的哪個位置。例如:

    CREATE TABLE MyTable (Col1 int PRIMARY KEY, Col2 binary)
    INSERT INTO MyTable VALUES (1, 0x7)
    

    由於轉換為二進位大型物件 (BLOB),因此查詢產生錯誤:

    SELECT Col1,
    CAST(Col2 as image) as Col2
    FROM MyTable
    FOR XML AUTO
    

    解決方法是將 BINARY BASE64 選項加入 FOR XML 子句中。若將轉換移除,則查詢會產生預期中的結果:

    SELECT Col1,
    Col2
    FROM MyTable
    FOR XML AUTO
    

    以下是結果:

    <MyTable Col1="1" Col2="dbobject/MyTable[@Col1='1']/@Col2" />
    
  • 在 SQL Server 2000 中,FOR XML 輸出可包含無效的 XML 字元。例如,十六進位值 7 可做為格式字元使用,但在其他情況下通常無法在輸出中當作文字檢視。目前,SQL Server 2005 已可在未使用 TYPE 指示詞的 FOR XML 查詢傳回這類字元時,將這些字元實體化。
    雖然不論這些字元是否已實體化,XML 1.0 相容剖析器都會引發剖析錯誤,但實體化格式與 XML 1.1 之間的相容性已有所提升。實體化格式與未來的 XML 標準版本之間也將具有較好的相容性。此外,它還可簡化偵錯作業,因為已可看見無效字元的字碼指標。
    對於 XML 工具的使用者,則不需使用任何解決方案,因為無論如何 XML 剖析器都會在資料流中出現無效字元時失敗。若您使用非 XML 工具,則此項變更需要您更新程式設計邏輯,使其搜尋這些做為實體化值的字元。

  • 在 SQL Server 2005 中,目前已可透過不同的方式在 FOR XML 查詢中實體化下列空白字元,而在往返過程中加以保留:

    • 在元素內容與屬性中:hex(0D) (歸位字元)
    • 在屬性內容中:hex(09) (索引標籤)、hex(0A) (換行字元)

    若您的應用程式原本設計為處理 SQL Server 2000 輸出 (其中會將這些字元正規化),則會受到影響。SQL Server 2005 輸出現在將會保留這些字元,剖析器不會再加以正規化。

請參閱

參考

使用 FOR XML 建構 XML

其他資源

SELECT (Transact-SQL)

說明及資訊

取得 SQL Server 2005 協助