Share via


類型系統 (XQuery)

XQuery 對結構描述類型而言是一個強式類型語言,對於不具類型的資料而言是一個弱式類型語言。XQuery 的預先定義類型包括下列各項:

此主題也描述下列項目:

XML 結構描述的內建類型

XML 結構描述的內建類型具有預先定義的命名空間前置詞 xs。其中一些類型包括 xs:integerxs: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 結構描述集合所提供。如需詳細資訊,請參閱<在 AdventureWorks 資料庫中的 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' )

下列範例中的運算式 (/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() 函數會從產品型號的所有 <Location> 元素中,擷取 LaborHours 屬性的具類型值。根據與 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() 函數來擷取節點的具類型值。