Ausdruckskontext und Ausdrucksauswertung (XQuery)

Der Kontext eines Ausdrucks sind die Informationen, die zum Analysieren und Auswerten des Ausdrucks verwendet werden. Die Auswertung von XQuery erfolgt in den folgenden beiden Phasen:

  • Statischer Kontext – Das ist die Phase der Abfragekompilierung. Auf der Basis der verfügbaren Informationen werden während dieser statischen Analyse der Abfrage manchmal Fehler ausgelöst.

  • Dynamischer Kontext – Das ist die Phase der Abfrageausführung. Selbst wenn eine Abfrage keine statischen Fehler wie z. B. Fehler während der Abfragekompilierung aufweist, kann die Abfrage trotzdem während ihrer Ausführung Fehler auslösen.

Statischer Kontext

Als Initialisierung des statischen Kontexts wird der Prozess bezeichnet, in dem alle Informationen für die statische Analyse des Ausdrucks zusammengestellt werden. Im Rahmen der Initialisierung des statischen Kontexts werden die folgenden Schritte durchgeführt:

  • Die boundary white space-Richtlinie wird auf strip-Konstruktionsmodus festgelegt. Deshalb wird das Grenzleerzeichen von den any element- und attribute-Konstruktoren in der Abfrage nicht beibehalten. Beispiel:

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

    Diese Abfrage gibt das folgende Ergebnis zurück, weil das Grenzleerzeichen beim Analysieren des XQuery-Ausdrucks entfernt wird:

    <a>Hello</a><b>Hello2</b>
    
  • Das Präfix und die Namespacebindung werden für folgende Namespaces initialisiert:

    • Einen Satz von vordefinierten Namespaces.

    • Alle mithilfe von WITH XMLNAMESPACES definierten Namespaces. Weitere Informationen finden Sie unter Hinzufügen von Namespaces mithilfe von WITH XMLNAMESPACES.

    • Alle im Abfrageprolog definierten Namespaces. Beachten Sie, dass die Namespacedeklarationen im Prolog die Namespacedeklaration in WITH XMLNAMESPACES überschreiben können. So wird z. B. in der folgenden Abfrage durch WITH XMLNAMESPACES ein Präfix (pd) deklariert, das die Bindung an den Namespace bewirkt (http://someURI). Diese Bindung wird jedoch in der WHERE-Klausel durch den Abfrageprolog überschrieben.

      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
      

    Alle diese Namespacebindungen werden bei der Initialisierung des statischen Kontexts aufgelöst.

  • Beim Abfragen einer typisierten xml-Spalte oder -Variablen werden die Komponenten der XML-Schemaauflistung, die der Spalte bzw. Variablen zugeordnet ist, in den statischen Kontext importiert. Weitere Informationen finden Sie unter Typisiertes XML im Vergleich zu nicht typisiertem XML.

  • Für jeden atomaren Typ in den importierten Schemas wird im statischen Kontext auch eine Umwandlungsfunktion verfügbar gemacht. Dies wird im folgenden Beispiel veranschaulicht. Im diesem Beispiel wird eine Abfrage für eine typisierte xml-Variable angegeben. Die dieser Variablen zugeordnete XML-Schemaauflistung definiert den atomaren Typ myType. Diesem Typ entsprechend ist während der statischen Analyse eine Umwandlungsfunktion mit der Bezeichnung myType() verfügbar. Der Abfrageausdruck (ns:myType(0)) gibt einen Wert von myType zurück.

    -- 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)')
    

    Im folgenden Beispiel ist die Umwandlungsfunktion für den integrierten XML-Typ int im Ausdruck angegeben.

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

Nachdem der statische Kontext initialisiert wurde, wird der Abfrageausdruck analysiert (kompiliert). Die statische Analyse umfasst die folgenden Schritte:

  1. Analysieren der Abfrage.

  2. Auflösen der im Ausdruck angegebenen Funktions- und Typnamen.

  3. Statisches Typisieren der Abfrage. Damit wird sichergestellt, dass die Abfrage typsicher ist. So gibt z. B. die folgende Abfrage einen statischen Fehler zurück, weil der +-Operator numerische Argumente mit primitiven Datentypen erfordert.

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

    Im folgenden Beispiel erfordert der value()-Operator einen Singleton-Wert. Wie im XML-Schema angegeben, kann es mehrere <Elem>-Elemente geben. Bei der statischen Analyse des Ausdrucks wird ermittelt, dass der Ausdruck nicht typsicher ist, und es wird ein statischer Fehler zurückgegeben. Um den Fehler aufzulösen, muss der Ausdruck so umgeschrieben werden, dass er explizit einen Singleton-Wert angibt (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)')
    

    Weitere Informationen finden Sie unter XQuery und statische Typisierung.

Einschränkungen für die Implementierung

Im Zusammenhang mit dem statischen Kontext gelten die folgenden Einschränkungen:

  • Der XPath-Kompatibilitätsmodus wird nicht unterstützt.

  • Für die XML-Konstruktion wird nur der strip-Konstruktionsmodus unterstützt. Dies ist die Standardeinstellung. Deshalb entspricht der Typ des konstruierten Elements dem xdt:untyped-Typ, und die Attribute weisen den xdt:untypedAtomic-Typ auf.

  • Es wird nur der der ordered-Sortiermodus strip XML unterstützt.

  • Es wird nur die strip-XML-Leerzeichenrichtlinie unterstützt.

  • Die Basis-URI-Funktionalität wird nicht unterstützt.

  • fn:doc() wird nicht unterstützt.

  • fn:collection() wird nicht unterstützt.

  • Es wird kein statischer Flagger für XQuery bereitgestellt.

  • Es wird die dem xml-Datentyp zugeordnete Sortierreihenfolge verwendet. Diese Sortierreihenfolge ist immer auf die Unicode-Codepunktsortierreichenfolge festgelegt.

Dynamischer Kontext

Unter dem dynamischen Kontext werden die Informationen verstanden, die zum Zeitpunkt der Ausführung des Ausdrucks verfügbar sein müssen. Zusätzlich zum statischen Kontext werden die folgenden Informationen als Bestandteil des dynamischen Kontexts initialisiert:

  • Der Schwerpunkt des Ausdrucks, z. B. das Kontext-Item, die Kontextposition und die Kontextgröße, werden entsprechend dem folgenden Beispiel initialisiert. Beachten Sie, dass alle diese Werte durch die nodes()-Methode überschrieben werden können.

    • Der xml-Datentyp legt das Kontext-Item, also den gerade verarbeiteten Knoten, auf den Dokumentknoten fest.

    • Die Kontextposition, also die Position des Kontext-Items im Verhältnis zu den gerade verarbeiteten Knoten, wird auf 1 festgelegt.

    • Die Kontextgröße, also die Anzahl der Items in der Sequenz, die gerade verarbeitet wird, wird zunächst auf 1 festgelegt, weil es immer einen Dokumentknoten gibt.

Einschränkungen für die Implementierung

Im Zusammenhang mit dem dynamischen Kontext gelten die folgenden Einschränkungen:

  • Die Kontextfunktionen Aktuelles Datum und aktuelle Uhrzeit, d. h. fn:current-date, fn:current-time und fn:current-dateTime, werden nicht unterstützt.

  • Die implizite Zeitzone ist auf UTC+0 festgelegt und kann nicht verändert werden.

  • Die fn:doc()-Funktion wird nicht unterstützt. Alle Abfragen werden für Spalten und Variablen des xml-Typs ausgeführt.

  • Die fn:collection()-Funktion wird nicht unterstützt.