運算式內容和查詢評估 (XQuery)

運算式的內容是用來分析和評估它的資訊。以下是評估 XQuery 的兩個階段:

  • 靜態內容 – 這是查詢編譯階段。依據可用的資訊,有時候錯誤是在靜態分析查詢期間引發。

  • 動態內容 – 這是查詢執行階段。即使查詢沒有靜態錯誤 (例如查詢編譯期間的錯誤),查詢仍可能在其執行期間傳回錯誤。

靜態內容

靜態內容初始化是指集中所有資訊,以進行運算式之靜態分析的過程。在靜態內容初始化的過程中,會完成下列項目:

  • 邊界空格原則設定為移除 (Strip)。因此,查詢中的 any element 和 attribute 建構函式不保留邊界空格。例如:

    declare @x xml
    set @x=''
    select @x.query('<a>  {"Hello"}  </a>,
    
        <b> {"Hello2"}  </b>')
    

    此查詢傳回下列結果,因為在剖析 XQuery 運算式的過程中移除了邊界空格:

    <a>Hello</a><b>Hello2</b>
    
  • 將針對下列各項,初始化前置詞和命名空間的繫結:

    • 一組預先定義的命名空間。

    • 任何使用 WITH XMLNAMESPACES 定義的命名空間。如需詳細資訊,請參閱<使用 WITH XMLNAMESPACES 來加入命名空間>。

    • 任何在查詢初構中定義的命名空間。請注意,初構中的命名空間宣告可能覆寫 WITH XMLNAMESPACES 中的命名空間宣告。例如,在下列查詢中,WITH XMLNAMESPACES 宣告將它繫結到命名空間 (http://someURI) 的前置詞 (pd)。不過,在 WHERE 子句中,查詢初構會覆寫繫結。

      WITH XMLNAMESPACES ('http://someURI' AS pd)
      SELECT ProductModelID, CatalogDescription.query('
          <Product 
              ProductModelID= "{ sql:column("ProductModelID") }" 
              />
      ') AS Result
      FROM Production.ProductModel
      WHERE CatalogDescription.exist('
          declare namespace  pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
           /pd:ProductDescription[(pd:Specifications)]'
          ) = 1
      

    所有這些命名空間繫結都是在靜態內容初始化期間解析的。

  • 如果查詢具類型的 xml 資料行或變數,與資料行或變數相關聯之 XML 結構描述集合的元件會匯入至靜態內容中。如需詳細資訊,請參閱<比較不具類型的 XML 與具類型的 XML>。

  • 對於所匯入之結構描述中的每一個不可部份完成類型,也可以在靜態內容中使用轉換函數。下列範例會加以說明。在此範例中,會針對具類型的 xml 變數指定查詢。與此變數相關聯之 XML 結構描述集合會定義不可部份完成類型 myType。在靜態分析期間,可使用對應於此類型的轉換函數 myType()。查詢運算式 (ns:myType(0)) 傳回 myType 的值。

    -- DROP XML SCHEMA COLLECTION SC
    -- go
    CREATE XML SCHEMA COLLECTION SC AS '<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="myNS" xmlns:ns="myNS"
    xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes">
          <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/>
          <simpleType name="myType">
                <restriction base="int">
                 <enumeration value="0" />
                  <enumeration value="1"/>
                </restriction>
          </simpleType>
          <element name="root" type="ns:myType"/>
    </schema>'
    go
    
    DECLARE @var XML(SC)
    SET @var = '<root xmlns="myNS">0</root>'
    -- specify myType() casting function in the query
    SELECT @var.query('declare namespace ns="myNS"; ns:myType(0)')
    

    在下列範例中,int 內建 XML 類型的轉換函數在運算式中加以指定。

    declare @x xml
    set @x = ''
    select @x.query('xs:int(5)')
    go
    

在靜態內容初始化之後,會分析 (編譯) 查詢運算式。靜態分析包含下列動作:

  1. 查詢剖析。

  2. 解析運算式中所指定的函數和類型名稱。

  3. 查詢的靜態類型 (Static Typing)。這可確定查詢為安全類型。例如,下列查詢傳回靜態錯誤,因為 + 運算子需要數值基本類型的引數:

    declare @x xml
    set @x=''
    SELECT @x.query('"x" + 4')
    

    在下列範例中,value() 運算子需要單一值。如 XML 結構描述中所指定,可以有多個 <Elem> 元素。運算式的靜態分析判斷它不是安全類型,而傳回靜態錯誤。若要解決此錯誤,必須將運算式重寫為明確指定單一值 (data(/x:Elem)[1])。

    DROP XML SCHEMA COLLECTION SC
    go
    CREATE XML SCHEMA COLLECTION SC AS '<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="myNS" xmlns:ns="myNS"
    xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes">
          <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/>
          <element name="Elem" type="string"/>
    </schema>'
    go
    
    declare @x xml (SC)
    set @x='<Elem xmlns="myNS">test</Elem><Elem xmlns="myNS">test2</Elem>'
    SELECT @x.value('declare namespace x="myNS"; data(/x:Elem)[1]','varchar(20)')
    

    如需詳細資訊,請參閱<XQuery 與靜態類型>。

實作限制

下列是與靜態內容相關的限制:

  • 不支援 XPath 相容性模式。

  • 若為 XML 建構,只支援 Strip 建構模式。這是預設值。因此,所建構之元素節點的類型是 xdt:untyped 類型,屬性是 xdt:untypedAtomic 類型。

  • 只支援已排序的順序模式。

  • 只支援「移除 XML 空格」原則。

  • 不支援基本 URI 功能。

  • 不支援 fn:doc() 。

  • 不支援 fn:collection()。

  • 不提供 XQuery Static Flagger。

  • 使用與 xml 資料類型相關聯的定序。此定序一律設為 Unicode 字碼指標定序。

動態內容

動態內容是指在執行運算式時必須提供的資訊。除了靜態內容之外,下列資訊也會初始化成為動態內容的一部份:

  • 運算式焦點如內容項目、內容位置和內容大小皆已初始化,如後文所示。請注意,所有這些值都可以被 nodes() 方法覆寫。

    • xml 資料類型將內容項目 (要處理的節點) 設為文件節點。

    • 內容位置 (即內容項目相對於所處理之節點的位置) 先設為 1。

    • 內容大小 (即所處理之序列的項目數) 先設為 1,因為每次都有一個文件節點。

實作限制

下列是與動態內容相關的限制:

  • 不支援 Current date and time 內容函數 fn:current-date、fn:current-time 和 fn:current-dateTime。

  • Implicit timezone 固定為 UTC+0,不能加以變更。

  • 不支援 fn:doc() 函數。所有查詢是針對 xml 類型資料行或變數來執行。

  • 不支援 fn:collection() 函數。