Teilen über


SequenceType-Ausdrücke (XQuery)

Gilt für:SQL Server

In XQuery ist jeder Wert eine Sequenz. Der Typ des Werts wird als Sequenztyp bezeichnet. Der Sequenztyp kann in einer Instanz des XQuery-Ausdrucks verwendet werden. Die in der XQuery-Spezifikation beschriebene SequenceType-Syntax wird verwendet, wenn in einem XQuery-Ausdruck auf einen Typ verwiesen werden muss.

Der name des atomischen Typs kann auch in der Umwandlung als XQuery-Ausdruck verwendet werden. In SQL Server werden die Instanz von und die Umwandlung als XQuery-Ausdrücke für SequenceTypes teilweise unterstützt.

instance of-Operator

Die Instanz des -Operators kann verwendet werden, um den dynamischen Oder Laufzeittyp des Werts des angegebenen Ausdrucks zu bestimmen. Beispiel:

  
Expression instance of SequenceType[Occurrence indicator]  

Beachten Sie, dass der instance of Operator , der Occurrence indicator, die Kardinalität und die Anzahl der Elemente in der resultierenden Sequenz angibt. Wenn dieser Operator nicht angegeben wird, wird eine Kardinalität von 1 verwendet. In SQL Server wird nur der Vorkommensindikator für Fragezeichen (?) unterstützt. Der Vorkommensindikator ? gibt an, dass Expression null oder ein Element zurückgeben kann. Wenn der Vorkommensindikator ? angegeben ist, gibt True zurück, instance of wenn der Expression Typ mit dem angegebenen SequenceTypeübereinstimmt, unabhängig davon, ob Expression ein Singleton oder eine leere Sequenz zurückgegeben wird.

Wenn der Vorkommensindikator ? nicht angegeben ist, gibt true nur zurück, sequence of wenn der Expression Typ mit dem Type angegebenen übereinstimmt und Expression ein Singleton zurückgibt.

Hinweis Das Pluszeichen (+) und das Sternchen (*) werden in SQL Server nicht unterstützt.

Die folgenden Beispiele veranschaulichen die Verwendung derInstanz des XQuery-Operators.

Beispiel A

Im folgenden Beispiel wird eine Xml-Typvariable erstellt und eine Abfrage dafür angegeben. Der Abfrageausdruck gibt einen instance of-Operator an, um zu bestimmen, ob der dynamische Typ des von dem ersten Operanden zurückgegebenen Werts mit dem im zweiten Operanden angegebenen Typ übereinstimmt.

Die folgende Abfrage gibt True zurück, da der Wert 125 eine Instanz des angegebenen Typs xs:integer ist:

declare @x xml  
set @x=''  
select @x.query('125 instance of xs:integer')  
go  

Die folgende Abfrage gibt True zurück, da der von dem Ausdruck (/a[1]) zurückgegebene Wert im ersten Operanden ein Element ist:

declare @x xml  
set @x='<a>1</a>'  
select @x.query('/a[1] instance of element()')  
go  

Entsprechend gibt instance of in der folgenden Abfrage True zurück, da der Werttyp des Ausdrucks im ersten Ausdruck ein Attribut ist:

declare @x xml  
set @x='<a attr1="x">1</a>'  
select @x.query('/a[1]/@attr1 instance of attribute()')  
go  

Im folgenden Beispiel gibt der Ausdruck data(/a[1] einen atomaren Wert mit der Typisierung xdt:untypedAtomic zurück. Folglich gibt instance of TRUE zurück.

declare @x xml  
set @x='<a>1</a>'  
select @x.query('data(/a[1]) instance of xdt:untypedAtomic')  
go  

In der folgenden Abfrage gibt der Ausdruck data(/a[1]/@attrA einen nicht typisierten atomaren Wert zurück. Folglich gibt instance of TRUE zurück.

declare @x xml  
set @x='<a attrA="X">1</a>'  
select @x.query('data(/a[1]/@attrA) instance of xdt:untypedAtomic')  
go  

Beispiel B

In diesem Beispiel fragen Sie eine typisierte XML-Spalte in der AdventureWorks-Beispieldatenbank ab. Die der abzufragenden Spalte zugeordnete XML-Schemaauflistung stellt die Typisierungsinformationen bereit.

Im Ausdruck gibt data() den typisierten Wert des ProductModelID-Attributs zurück, dessen Typ xs:string gemäß dem der Spalte zugeordneten Schema ist. Folglich gibt instance of TRUE zurück.

SELECT CatalogDescription.query('  
   declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
   data(/PD:ProductDescription[1]/@ProductModelID) instance of xs:string  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID = 19  

Weitere Informationen finden Sie unter Vergleichen von typisiertem XML mit nicht typisiertem XML.

Die folgenden Abfragen verwenden denBoolean-Ausdruck instance of , um zu bestimmen, ob das LocationID-Attribut vom Typ xs:integer ist:

SELECT Instructions.query('  
   declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
   /AWMI:root[1]/AWMI:Location[1]/@LocationID instance of attribute(LocationID,xs:integer)  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID=7  

Die folgende Abfrage wird für die typisierte CatalogDescription-Spalte vom Typ XML angegeben. Die dieser Spalte zugeordnete XML-Schemaauflistung stellt die Typisierungsinformationen bereit.

Die Abfrage verwendet den element(ElementName, ElementType?)-Test im instance of-Ausdruck, um zu überprüfen, ob /PD:ProductDescription[1] einen Elementknoten eines bestimmten Namens und Typs zurückgibt.

SELECT CatalogDescription.query('  
     declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
     /PD:ProductDescription[1] instance of element(PD:ProductDescription, PD:ProductDescription?)  
    ') as Result  
FROM  Production.ProductModel  
where ProductModelID=19  

Diese Abfrage gibt True zurück.

Beispiel C

Bei Verwendung von Union-Typen weist der instance of Ausdruck in SQL Server eine Einschränkung auf: Insbesondere wenn der Typ eines Elements oder Attributs ein Union-Typ ist, instance of bestimmt möglicherweise nicht den genauen Typ. Folglich gibt eine Abfrage False zurück, es sei denn, der in SequenceType verwendete atomare Typ ist das höchste übergeordnete Element des aktuellen Typs des Ausdrucks in der simpleType-Hierarchie. Mit anderen Worten müssen die in SequenceType angegebenen atomaren Typen dem Typ anySimpleType direkt untergeordnet sein. Informationen zur Typhierarchie finden Sie unter Type Casting Rules in XQuery.

Das nächste Abfragebeispiel führt folgende Vorgänge aus:

  • Erstellen einer XML-Schemaauflistung und Definieren eines UNION-Typs wie integer oder string.

  • Deklarieren Sie eine typisierte XML-Variable mithilfe der XML-Schemaauflistung.

  • Zuordnen einer XML-Beispielinstanz zu der Variablen.

  • Abfragen der Variablen, um das Verhalten von instance of mit einem UNION-Typ zu veranschaulichen.

Im Folgenden wird die Abfrage aufgeführt:

CREATE XML SCHEMA COLLECTION MyTestSchema AS '  
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ns" xmlns:ns="http://ns">  
<simpleType name="MyUnionType">  
<union memberTypes="integer string"/>  
</simpleType>  
<element name="TestElement" type="ns:MyUnionType"/>  
</schema>'  
Go  

Die folgende Abfrage gibt False zurück, da der in dem instance of-Ausdruck angegebene Sequenztyp nicht das höchste übergeordnete Element des aktuellen Typs des angegebenen Ausdrucks ist. Das heißt, der Wert von <TestElement> ist ein ganzzahliger Typ. das höchste übergeordnete Element ist xs:decimal. Es ist jedoch nicht als der zweite Operand des instance of-Operators angegeben.

SET QUOTED_IDENTIFIER ON  
DECLARE @var XML(MyTestSchema)  
  
SET @var = '<TestElement xmlns="http://ns">123</TestElement>'  
  
SELECT @var.query('declare namespace ns="http://ns"   
   data(/ns:TestElement[1]) instance of xs:integer')  
go  

Nachdem das höchste übergeordnete Element von xs:integer xs:decimal ist, würde die Abfrage True zurückgeben, wenn Sie sie ändern und xs:decimal als SequenceType angeben.

SET QUOTED_IDENTIFIER ON  
DECLARE @var XML(MyTestSchema)  
SET @var = '<TestElement xmlns="http://ns">123</TestElement>'  
SELECT @var.query('declare namespace ns="http://ns"     
   data(/ns:TestElement[1]) instance of xs:decimal')  
go  

Beispiel D

In diesem Beispiel erstellen Sie zunächst eine XML-Schemaauflistung und verwenden sie zum Eingeben einer XML-Variablen . Die typisierte XML-Variable wird dann abgefragt, um die instance of Funktionalität zu veranschaulichen.

Die folgende XML-Schemaauflistung definiert den einfachen Typ myType und ein Element vom <root>Typ 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="s:varchar">  
                  <maxLength value="20"/>  
            </restriction>  
      </simpleType>  
      <element name="root" type="ns:myType"/>  
</schema>'  
Go  

Erstellen Sie nun eine typisierte XML-Variable , und fragen Sie sie ab:

DECLARE @var XML(SC)  
SET @var = '<root xmlns="myNS">My data</root>'  
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";  
declare namespace ns="myNS";   
   data(/ns:root[1]) instance of ns:myType')  
go  

Nachdem der myType-Typ durch Einschränkung aus einem im sqltpypes-Schema definierten varchar-Typ abgeleitet ist, gibt instance of ebenfalls True zurück.

DECLARE @var XML(SC)  
SET @var = '<root xmlns="myNS">My data</root>'  
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";  
declare namespace ns="myNS";   
data(/ns:root[1]) instance of sqltypes:varchar?')  
go  

Beispiel E

Im folgenden Beispiel ruft der Ausdruck einen der Werte des IDREFS-Attributs auf und verwendet instance of, um zu bestimmen, ob der Wert vom Typ IDREF ist. Das Beispiel führt die folgenden Aktionen aus:

  • Erstellt eine XML-Schemaauflistung, in der das <Customer> Element über ein OrderList IDREFS-Typattribute und das <Order> Element über ein Attribut vom Typ "OrderID ID" verfügt.

  • Erstellt eine typisierte XML-Variable und weist ihr eine XML-Beispielinstanz zu.

  • Gibt eine Abfrage für die Variable an. Der Abfrageausdruck ruft den ersten Auftrags-ID-Wert aus dem OrderList IDRERS-Typattribute des ersten <Customer>ab. Der abgerufene Wert ist vom Typ IDREF. Folglich gibt instance of True zurück.

create xml schema collection SC as  
'<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:Customers="Customers" targetNamespace="Customers">  
            <element name="Customers" type="Customers:CustomersType"/>  
            <complexType name="CustomersType">  
                        <sequence>  
                            <element name="Customer" type="Customers:CustomerType" minOccurs="0" maxOccurs="unbounded" />  
                        </sequence>  
            </complexType>  
             <complexType name="OrderType">  
                <sequence minOccurs="0" maxOccurs="unbounded">  
                            <choice>  
                                <element name="OrderValue" type="integer" minOccurs="0" maxOccurs="unbounded"/>  
                            </choice>  
                </sequence>                                             
                <attribute name="OrderID" type="ID" />  
            </complexType>  
  
            <complexType name="CustomerType">  
                <sequence minOccurs="0" maxOccurs="unbounded">  
                            <choice>  
                                <element name="spouse" type="string" minOccurs="0" maxOccurs="unbounded"/>  
                                <element name="Order" type="Customers:OrderType" minOccurs="0" maxOccurs="unbounded"/>  
                            </choice>  
                </sequence>                                             
                <attribute name="CustomerID" type="string" />  
                <attribute name="OrderList" type="IDREFS" />  
            </complexType>  
 </schema>'  
go  
declare @x xml(SC)  
set @x='<CustOrders:Customers xmlns:CustOrders="Customers">  
                <Customer CustomerID="C1" OrderList="OrderA OrderB"  >  
                              <spouse>Jenny</spouse>  
                                <Order OrderID="OrderA"><OrderValue>11</OrderValue></Order>  
                                <Order OrderID="OrderB"><OrderValue>22</OrderValue></Order>  
  
                </Customer>  
                <Customer CustomerID="C2" OrderList="OrderC OrderD" >  
                                <spouse>John</spouse>  
                                <Order OrderID="OrderC"><OrderValue>33</OrderValue></Order>  
                                <Order OrderID="OrderD"><OrderValue>44</OrderValue></Order>  
  
                        </Customer>  
                <Customer CustomerID="C3"  OrderList="OrderE OrderF" >  
                                <spouse>Jane</spouse>  
                                <Order OrderID="OrderE"><OrderValue>55</OrderValue></Order>  
                                <Order OrderID="OrderF"><OrderValue>55</OrderValue></Order>  
                </Customer>  
                <Customer CustomerID="C4"  OrderList="OrderG"  >  
                                <spouse>Tim</spouse>  
                                <Order OrderID="OrderG"><OrderValue>66</OrderValue></Order>  
                        </Customer>  
                <Customer CustomerID="C5"  >  
                </Customer>  
                <Customer CustomerID="C6" >  
                </Customer>  
                <Customer CustomerID="C7"  >  
                </Customer>  
</CustOrders:Customers>'  
  
select @x.query(' declare namespace CustOrders="Customers";   
 data(CustOrders:Customers/Customer[1]/@OrderList)[1] instance of xs:IDREF ? ') as XML_result  

Implementierungseinschränkungen

Die folgenden Einschränkungen sind zu beachten:

  • Die Sequenztypen schema-element() und schema-attribute() werden für den Vergleich mit dem instance of Operator nicht unterstützt.

  • Vollständige Sequenzen wie z. B. (1,2) instance of xs:integer* werden nicht unterstützt.

  • Wenn Sie eine Form des Element() -Sequenztyps verwenden, die einen Typnamen angibt, z element(ElementName, TypeName). B. , muss der Typ mit einem Fragezeichen (?) qualifiziert werden. element(Title, xs:string?) gibt beispielsweise an, dass für das Element NULL-Werte zulässig sind. SQL Server unterstützt keine Laufzeiterkennung der xsi:nil-Eigenschaft mithilfe instance ofvon .

  • Wenn der Wert in Expression aus einem Element oder Attribut stammt, das als Union typisiert wurde, kann SQL Server nur den primitiven, nicht abgeleiteten Typ identifizieren, von dem der Werttyp abgeleitet wurde. Wenn <e1> beispielsweise für den statischen Typ (xs:integer | xs:string) definiert ist, gibt folgendes False zurück.

    data(<e1>123</e1>) instance of xs:integer  
    

    Jedoch gibt data(<e1>123</e1>) instance of xs:decimal True zurück.

  • Für die Sequenztypen processing-instruction() und document-node() sind nur Formulare ohne Argumente zulässig. Beispielsweise processing-instruction() ist zulässig, aber processing-instruction('abc') nicht zulässig.

cast as-Operator

Die Umwandlung als Ausdruck kann verwendet werden, um einen Wert in einen bestimmten Datentyp zu konvertieren. Zum Beispiel:

  
Expression cast as  AtomicType?  

In SQL Server ist das Fragezeichen (?) nach erforderlichAtomicType. Beispielsweise konvertiert, wie in der folgenden Abfrage gezeigt, "2" cast as xs:integer? den Zeichenfolgenwert in eine ganze Zahl:

declare @x xml  
set @x=''  
select @x.query('"2" cast as xs:integer?')  

In der folgenden Abfrage gibt data() den typisierten Wert des ProductModelID-Attributs zurück, einen Zeichenfolgentyp. Der cast asOperator konvertiert den Wert in xs:integer.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD)  
SELECT CatalogDescription.query('  
   data(/PD:ProductDescription[1]/@ProductModelID) cast as xs:integer?  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID = 19  

Die explizite Verwendung von data() ist in dieser Abfrage nicht erforderlich. Der cast as-Ausdruck führt die implizite Atomisierung des Eingabeausdrucks aus.

Konstruktorfunktionen

Sie können die Konstruktorfunktionen für atomare Typen verwenden. Anstatt beispielsweise den cast as Operator zu verwenden, "2" cast as xs:integer?können Sie die Konstruktorfunktion xs:integer() verwenden, wie im folgenden Beispiel gezeigt:

declare @x xml  
set @x=''  
select @x.query('xs:integer("2")')  

Das folgende Beispiel gibt einen Datumswert vom Typ xs:date gleich 2000-01-01Z zurück.

declare @x xml  
set @x=''  
select @x.query('xs:date("2000-01-01Z")')  

Sie können Konstruktoren auch für benutzerdefinierte atomare Typen verwenden. Wenn beispielsweise die xml-Schemaauflistung, die dem XML-Datentyp zugeordnet ist, einen einfachen Typ definiert, kann ein myType() -Konstruktor verwendet werden, um einen Wert dieses Typs zurückzugeben.

Implementierungseinschränkungen

  • Die XQuery-Ausdrücke typeswitch, castable und treat werden nicht unterstützt.

  • Cast as erfordert ein Fragezeichen (?) nach dem atomischen Typ.

  • xs:QName wird als Typ für die Umwandlung nicht unterstützt. Verwenden Sie stattdessen expanded-QName .

  • xs:date, xs:time und xs:datetime erfordern eine Zeitzone, die durch ein Z angegeben wird.

    Die folgende Abfrage schlägt fehl, da die Zeitzone nicht angegeben ist.

    DECLARE @var XML  
    SET @var = ''  
    SELECT @var.query(' <a>{xs:date("2002-05-25")}</a>')  
    go  
    

    Wenn Sie dem Wert ein Z zum Anzeigen der Zeitzone hinzufügen, kann die Abfrage ordnungsgemäß ausgeführt werden.

    DECLARE @var XML  
    SET @var = ''  
    SELECT @var.query(' <a>{xs:date("2002-05-25Z")}</a>')  
    go  
    

    Dies ist das Ergebnis:

    <a>2002-05-25Z</a>  
    

Weitere Informationen

XQuery-Ausdrücke
Type System (XQuery) (Typensystem (XQuery))