分享方式:


XQuery 中的類型轉換規則

適用於:SQL Server

下列 W3C XQuery 1.0 和 XPath 2.0 函數和運算子規格圖表顯示內建資料類型。 這包括內建基本型別和內建衍生型別。

XQuery 1.0 type hierarchy

本主題描述使用下列其中一種方法,從某個類型轉換成另一個類型時所套用的類型轉換規則:

  • 使用 cast 作為 或型別建構函式來執行的明確轉換(例如 , xs:integer("5")

  • 類型升級期間發生的隱含轉換

明確轉換

下表概述內建基本類型之間的允許類型轉換。

Describes casting rules for XQuery.

  • 內建基本類型可以根據資料表中的規則,轉換成另一個內建基本類型。

  • 基本類型可以轉換成衍生自該基本類型的任何類型。 例如,您可以從 xs:decimal 轉換為 xs:integer ,或從 xs:decimal 轉換為 xs:long

  • 衍生型別可以轉換成類型階層中其上階的任何類型,一路到其內建基本基底類型為止。 例如,您可以將 xs :token 轉換成 xs:normalizedString xs:string

  • 如果衍生型別可以轉換成目標型別,則其基本祖系可以轉換成基本類型。 例如,您可以將 xs:integer 、衍生類型轉換成 xs:string 、基本類型 ,因為 xs:decimal xs:integer 的基本祖系可以轉換成 xs:string

  • 如果來源類型的基本上階可以轉換成目標型別的基本祖系,則可以將衍生類型轉換成另一個衍生型別。 例如,您可以從 xs:integer 轉換成 xs:token ,因為您可以從 xs:decimal 轉換成 xs:string

  • 將使用者定義型別轉換成內建型別的規則,與內建型別的規則相同。 例如,您可以定義 衍生自 xs:integer 類型的 myInteger 類型。 然後, myInteger 可以轉換成 xs:token ,因為 xs:decimal 可以轉換成 xs:string

不支援下列類型的轉型:

  • 不允許轉換至清單類型或從清單類型轉換。 這包括使用者定義的清單類型和內建清單類型,例如 xs:IDREFS xs:ENTITIES xs:NMTOKENS

  • 不支援轉換至 xs:QName 或從 xs:QName 轉換。

  • 不支援 xs:NOTATION 和持續時間的完整 排序子類型 xdt:yearMonthDuration 和 xdt:dayTimeDuration 。 因此,不支援從這些類型轉換或轉換。

下列範例說明明確的類型轉換。

範例 A

下列範例會查詢 xml 類型變數。 查詢會傳回類型為 xs:string 的簡單型別值序列。

declare @x xml  
set @x = '<e>1</e><e>2</e>'  
select @x.query('/e[1] cast as xs:string?')  
go  

範例 B

下列範例會查詢具類型的 xml 變數。 此範例會先建立 XML 架構集合。 然後,它會使用 XML 架構集合來建立具類型的 xml 變數。 架構會提供指派給變數之 XML 實例的輸入資訊。 接著會針對 變數指定查詢。

create xml schema collection myCollection as N'  
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">  
      <xs:element name="root">  
            <xs:complexType>  
                  <xs:sequence>  
                        <xs:element name="A" type="xs:string"/>  
                        <xs:element name="B" type="xs:string"/>  
                        <xs:element name="C" type="xs:string"/>  
                  </xs:sequence>  
            </xs:complexType>  
      </xs:element>  
</xs:schema>'  
go  

下列查詢會傳回靜態錯誤,因為您不知道檔實例中有多少最上層 <root> 元素。

declare @x xml(myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>  
          <root><A>4</A><B>5</B><C>6</baz></C>'  
select @x.query('/root/A cast as xs:string?')  
go  

藉由在運算式中指定單 <root> 一元素,查詢就會成功。 查詢會傳回類型為 xs:string 的簡單型別值序列。

declare @x xml(myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>  
              <root><A>4</A><B>5</B><C>6</C></root>'  
select @x.query('/root[1]/A cast as xs:string?')  
go  

在下列範例中,xml 類型變數包含指定 XML 架構集合的檔關鍵字。 這表示 XML 實例必須是具有單一最上層元素的檔。 如果您在 XML 實例中建立兩 <root> 個元素,則會傳回錯誤。

declare @x xml(document myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>  
              <root><A>4</A><B>5</B><C>6</C></root>'  
go  

您可以變更 實例,只包含一個最上層元素,而且查詢可以運作。 同樣地,查詢會傳回類型為 xs:string 的簡單型別值序列。

declare @x xml(document myCollection)  
set @x = '<root><A>1</A><B>2</B><C>3</C></root>'  
select @x.query('/root/A cast as xs:string?')  
go  

隱含轉換

隱含轉換只允許用於數數值型別和不具類型的不可部分完成類型。 例如,下列 min() 函式會傳回兩個值的最小值:

min(xs:integer("1"), xs:double("1.1"))  

在此範例中,傳入 XQuery min() 函式的兩個值是不同類型的值。 因此,會執行隱含轉換,其中 整數 類型升階為 double,而且會比較兩個 雙精度 點數。

此範例中所述的類型升級會遵循下列規則:

  • 內建衍生的數數值型別可能會升階為其基底類型。 例如, 整數 可能會升階為 十進位

  • 小數 點可能會升階為 float, float 可能會升階為 double

因為隱含轉換只允許用於數數值型別,因此不允許下列專案:

  • 不允許字串類型的隱含轉換。 例如,如果預期有兩 字串 類型,而且您傳入字串 和權杖 ,則不會發生隱含轉換,並傳回錯誤。

  • 不允許從數數值型別隱含轉換成字串類型。 例如,如果您將整數類型值傳遞至預期字串類型參數的函式,則不會發生隱含轉換,並傳回錯誤。

轉換值

從某個類型轉換成另一個類型時,實際值會從來源類型的值空間轉換成目標型別的值空間。 例如,從 xs:decimal 轉換成 xs:double 會將十進位值轉換成雙精度浮點數。

以下是一些轉換規則。

從字串或 untypedAtomic 類型轉換值

轉換成字串或 untypedAtomic 類型的值會以與根據目標型別規則驗證值的方式轉換。 這包括最終模式和空白字元處理規則。 例如,下列專案會成功並產生雙精度浮點數 1.1e0:

xs:double("1.1")

從字串或 untypedAtomic 類型轉換成 xs:base64Binary 或 xs:hexBinary 等二進位類型時,輸入值必須分別以 base64 或十六進位編碼。

將值轉換成字串或 untypedAtomic 類型

轉換成字串或不具類型的Atomic 類型會將值轉換成其 XQuery 標準語匯標記法。 具體來說,這可能表示輸入期間可能已遵守特定模式或其他條件約束的值將不會根據該條件約束來表示。 若要通知使用者這一點,SQL Server 會旗標類型,其中類型條件約束可能是問題,方法是在那些類型載入架構集合時提供警告。

將 xs:float 或 xs:double 類型或任一子類型的值轉換成字串或 untypedAtomic 類型時,值會以科學標記法表示。 只有當值的絕對值小於 1.0E-6,或大於或等於 1.0E6 時,才會這麼做。 這表示 0 會以科學標記法序列化為 0.0E0。

例如, xs:string(1.11e1) 會傳回字串值 "11.1" ,而 xs:string(-0.00000000002e0) 會傳回字串值 "-2.0E-11"

將 xs:base64Binary 或 xs:hexBinary 等二進位類型轉換成字串或 untypedAtomic 類型時,二進位值會分別以 base64 或十六進位編碼形式表示。

將值轉換成數數值型別

將某個數值型別的值轉換成另一個數值型別的值時,值會從一個值空間對應到另一個值,而不會經過字串序列化。 如果值不符合目標型別的條件約束,則會套用下列規則:

  • 如果來源值已經是數值,而且目標型別是 xs:float 或允許 -INF 或 IN光圈值的子類型,而且來源數值的轉換會導致溢位,則如果值為正數,則值會對應至 INF,如果值為正數,則為 -INF。 如果目標型別不允許 INF 或 -INF,而且會發生溢位,轉換會失敗,而且此版本的 SQL Server 的結果是空序列。

  • 如果來源值已經是數值,且目標型別是包含 0、-0e0 或 0e0 的數數值型別,且來源數值的轉換會導致下溢,則值會以下列方式對應:

    • 值會對應至 0 作為小數目標型別。

    • 當值為負下溢時,值會對應至 -0e0。

    • 當值為浮點數或雙精度浮點數目標型別的正下溢時,值會對應至 0e0。

    如果目標型別在其值空間中不包含零,則轉換會失敗,結果為空序列。

    請注意,將值轉換成二進位浮點類型,例如 xs:float、xs:double 或其任何子類型,可能會失去精確度。

實作限制

以下是限制:

  • 不支援浮點值 NaN。

  • 可轉換的值受限於目標型別實作限制。 例如,您無法將負年份 的日期字串轉換成 xs:date 。 如果在執行時間提供值,則這類轉換會導致空序列(而不是引發執行階段錯誤)。

另請參閱

定義 XML 資料的序列化