最近工作上需要將資料庫內的資料轉換成XML,稍微瞭解了一下MS SQL所提供的XML語法,做一些簡單的Lab,並記錄下來。
建立測試用Table及資料:首先建立一個暫時性的Table,作為Lab的資料來源。
CREATE TABLE #Orders
(
OrderUID INT NOT NULL IDENTITY,
Customer NVARCHAR( 100),
Item NVARCHAR( 200),
Quantity INT NOT NULL
)
INSERT INTO #Orders(Customer, Item, Quantity)
VALUES ('Foo', '可樂', 10)
INSERT INTO #Orders(Customer, Item, Quantity)
VALUES ('Boo', '餅乾', 20)
INSERT INTO #Orders(Customer, Item, Quantity)
VALUES ('Boo', '甜甜圈', 30)
FOR XML的模式
RAW模式
RAW模式會將查詢結果集的每一資料列轉成一個XML Element
,並以row當作Element名稱,每個欄位則會以Attribute的形式顯示。
SQL Statement
SELECT Customer, Item, Quantity
FROM #Orders
FOR XML RAW
結果會是
<row Customer="Foo" Item="可樂" Quantity="10" />
<row Customer="Boo" Item="餅乾" Quantity="20" />
<row Customer="Boo" Item="甜甜圈" Quantity="30" />
AUTO模式
將查詢結果以簡易巢狀 XML 樹狀結構傳回,會以Table名稱當作row Element
的名稱
SQL Statement
SELECT Customer, Item, Quantity
FROM #Orders
FOR XML AUTO
結果會是(因為是Temp Table,所以Table名稱會加上系統設定的前置詞)
<_x0023_Orders Customer="Foo" Item="可樂" Quantity="10" />
<_x0023_Orders Customer="Boo" Item="餅乾" Quantity="20" />
<_x0023_Orders Customer="Boo" Item="甜甜圈" Quantity="30" />
PATH模式
MSDN上的說明如下,看起來是可以較靈活且簡單的定義XML輸出格式:
提供更簡單的方式來混合元素與屬性,並引用其他的巢狀來代表複雜的屬性。您可以使用 EXPLICIT 模式查詢來建構從資料列集而來的這類 XML,但是 PATH 模式對於可能會比較繁雜的 EXPLICIT 模式查詢提供較簡單的替代方案。
SQL Statement
SELECT Customer, Item, Quantity
FROM #Orders
FOR XML PATH
結果會是
<row>
<Customer>Foo</Customer>
<Item>可樂</Item>
<Quantity>10</Quantity>
</row>
<row>
<Customer>Boo</Customer>
<Item>餅乾</Item>
<Quantity>20</Quantity>
</row>
<row>
<Customer>Boo</Customer>
<Item>甜甜圈</Item>
<Quantity>30</Quantity>
</row>
EXPLICIT模式
在MSDN的說明中,EXPLICIT模式可以最大幅度的控制XML產出形式。
RAW 和 AUTO 模式對從查詢結果產生之 XML 形式的控制不大。 但是,EXPLICIT 模式在由查詢結果產生想要的 XML 方面,可提供的彈性最大。
只是也有許多語法細節要注意,所以就沒有進一步的研究下去。可以參考:搭配 FOR XML 使用 EXPLICIT 模式
指示詞
使用ELEMENTS指示詞
如果在句尾加上 ,ELEMENTS
,則每個欄位都會以XML Element的形式產生。
SQL Statement:
SELECT Customer, Item, Quantity
FROM #Orders
FOR XML RAW, ELEMENTS
結果會是:
<row>
<Customer>Foo</Customer>
<Item>可樂</Item>
<Quantity>10</Quantity>
</row>
<row>
<Customer>Boo</Customer>
<Item>餅乾</Item>
<Quantity>20</Quantity>
</row>
<row>
<Customer>Boo</Customer>
<Item>甜甜圈</Item>
<Quantity>30</Quantity>
</row>
使用ROOT指示詞
使用ROOT指示詞,可以產生並指定所產出的XML的根標籤名稱。
以下SQL Statement會產生根標籤為Order
的XML:
SELECT Customer, Item, Quantity
FROM #Orders
FOR XML RAW, ROOT('Order')
產生的XML為
<Order>
<row Customer="Foo" Item="可樂" Quantity="10" />
<row Customer="Boo" Item="餅乾" Quantity="20" />
<row Customer="Boo" Item="甜甜圈" Quantity="30" />
</Order>
使用XMLDATA 與 XMLSCHEMA
使用XMLDATA
會回傳帶有結構描述的XML
SQL Statement:
SELECT Customer, Item, Quantity
FROM #Orders
FOR XML RAW, XMLDATA
結果會是:
<Schema name="Schema1" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<ElementType name="row" content="empty" model="closed">
<AttributeType name="Customer" dt:type="string" />
<AttributeType name="Item" dt:type="string" />
<AttributeType name="Quantity" dt:type="i4" />
<attribute type="Customer" />
<attribute type="Item" />
<attribute type="Quantity" />
</ElementType>
</Schema>
<row xmlns="x-schema:#Schema1" Customer="Foo" Item="可樂" Quantity="10" />
<row xmlns="x-schema:#Schema1" Customer="Boo" Item="餅乾" Quantity="20" />
<row xmlns="x-schema:#Schema1" Customer="Boo" Item="甜甜圈" Quantity="30" />
如果要回傳的是XSD結構描述的XML格式,則使用XMLSCHEMA
SQL Statement:
SELECT Customer, Item, Quantity
FROM #Orders
FOR XML RAW, XMLSCHEMA
結果會是:
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="row">
<xsd:complexType>
<xsd:attribute name="Customer">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1028" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">
<xsd:maxLength value="100" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="Item">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1028" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">
<xsd:maxLength value="200" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="Quantity" type="sqltypes:int" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" Customer="Foo" Item="可樂" Quantity="10" />
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" Customer="Boo" Item="餅乾" Quantity="20" />
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1" Customer="Boo" Item="甜甜圈" Quantity="30" />