類型系統 (XQuery)
適用於:SQL Server
XQuery 是架構類型的強型別語言,以及不具型別資料的弱型別語言。 預先定義的 XQuery 類型包括下列專案:
命名空間中 XML 架構的 http://www.w3.org/2001/XMLSchema 內建類型。
命名空間中 http://www.w3.org/2004/07/xpath-datatypes 定義的類型。
本主題也會描述下列各項:
具型別值與節點的字串值比較。
比對運算式傳回的序列類型。
XML 架構的內建類型
XML 架構的內建類型具有 xs 的預先定義命名空間前置詞。 其中有些類型包括 xs:integer 和 xs:string 。 支援所有這些內建類型。 當您建立 XML 架構集合時,可以使用這些類型。
查詢具類型的 XML 時,節點的靜態和動態類型是由與所查詢之資料行或變數相關聯的 XML 架構集合所決定。 如需靜態和動態類型的詳細資訊,請參閱 運算式內容和查詢評估 (XQuery) 。 例如,下列查詢是針對具類型的 xml 資料行指定 ( Instructions
)。 運算式會使用 instance of
來驗證傳回之屬性的 LotSize
具型別值是否為 型別 xs:decimal
。
SELECT Instructions.query('
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
data(/AWMI:root[1]/AWMI:Location[@LocationID=10][1]/@LotSize)[1] instance of xs:decimal
') AS Result
FROM Production.ProductModel
WHERE ProductModelID=7
這個輸入資訊是由與資料行相關聯的 XML 架構集合所提供。
XPath 資料類型命名空間中定義的類型
命名空間中 http://www.w3.org/2004/07/xpath-datatypes 定義的型別具有 xdt 的 預先定義前置詞。 下列適用于下列類型:
當您建立 XML 架構集合時,無法使用這些類型。 這些類型用於 XQuery 類型系統,並用於 XQuery 和靜態類型 。 您可以在 xdt 命名空間中 轉換成不可部分完成的類型, 例如 xdt:untypedAtomic 。
查詢不具類型的 XML 時,元素節點的靜態和動態類型為 xdt:untyped ,而屬性值的類型為 xdt:untypedAtomic 。 query() 方法的結果 會產生不具類型的 XML。 這表示 XML 節點會分別以 xdt:untyped 和 xdt:untypedAtomic 傳回。
不支援 xdt:dayTimeDuration 和 xdt:yearMonthDuration 類型。
在下列範例中,會針對不具類型的 XML 變數指定查詢。 運算式 會 data(/a[1]
傳回一個不可部分完成值的序列。 函 data()
式會傳回 專案的 <a>
具型別值。 由於所查詢的 XML 不是類型,因此傳回之值的型別為 xdt:untypedAtomic
。 因此, instance of
會傳回 true。
DECLARE @x xml
SET @x='<a>20</a>'
SELECT @x.query( 'data(/a[1]) instance of xdt:untypedAtomic' )
下列範例中的 expression ( /a[1]
) 不是擷取具型別的值,而是傳回一個元素 <a>
的專案序列。 運算式 instance of
會使用元素測試來確認運算式所傳回的值是否為 的專案 xdt:untyped type
節點。
DECLARE @x xml
SET @x='<a>20</a>'
-- Is this an element node whose name is "a" and type is xdt:untyped.
SELECT @x.query( '/a[1] instance of element(a, xdt:untyped?)')
-- Is this an element node of type xdt:untyped.
SELECT @x.query( '/a[1] instance of element(*, xdt:untyped?)')
-- Is this an element node?
SELECT @x.query( '/a[1] instance of element()')
注意
當您查詢具類型的 XML 實例,而查詢運算式包含父軸時,產生的節點靜態類型資訊就無法再使用。 不過,動態類型仍與節點相關聯。
具類型的值與字串值
每個節點都有具類型的值和字串值。 針對具類型的 XML 資料,具型別值的型別是由與所查詢之資料行或變數相關聯的 XML 架構集合所提供。 對於不具類型的 XML 資料,具型別值的型別為 xdt:untypedAtomic 。
您可以使用 data() 或 string() 函式來擷取節點的值:
在下列 XML 架構集合中, <root
> 會定義整數類型的 元素:
CREATE XML SCHEMA COLLECTION SC AS N'
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="root" type="integer"/>
</schema>'
GO
在下列範例中,運算式會先擷取 的 /root[1]
具型別值,然後將 它加入 3
其中。
DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('data(/root[1]) + 3')
在下一個範例中,運算式會失敗,因為 string(/root[1])
運算式中的 會傳回字串類型值。 接著,這個值會傳遞至算術運算子,該運算子只會接受數值型別值做為其運算元。
-- Fails because the argument is string type (must be numeric primitive type).
DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('string(/root[1]) + 3')
下列範例會計算屬性的 LaborHours
總計。 函 data()
式會 LaborHours
從產品模型的所有 <Location
> 元素擷取屬性值。 根據與 Instruction
資料行相關聯的 XML 架構, LaborHours
是 xs:decimal 類型。
SELECT Instructions.query('
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
sum(data(//AWMI:Location/@LaborHours))
') AS Result
FROM Production.ProductModel
WHERE ProductModelID=7
此查詢會傳回 12.75 作為結果。
注意
在此範例中,明確使用 data() 函式僅供說明。 如果未指定, sum() 會隱含地套用 data() 函式來擷取節點的具型別值。