Dela via


SequenceType-uttryck (XQuery)

gäller för:SQL Server

I XQuery är ett värde alltid en sekvens. Typen av värde kallas för en sekvenstyp. Sekvenstypen kan användas i en instans av XQuery-uttryck. SequenceType-syntaxen som beskrivs i XQuery-specifikationen används när du behöver referera till en typ i ett XQuery-uttryck.

Namnet på atomtypen kan också användas i som XQuery-uttryck. I SQL Server stöds delvis den instansen av och som XQuery-uttryck på SequenceTypes.

instans av Operator

Den instansen av-operatorn kan användas för att fastställa den dynamiska typen eller körningstypen för värdet för det angivna uttrycket. Till exempel:

  
Expression instance of SequenceType[Occurrence indicator]  

Observera att operatorn instance of, Occurrence indicator, anger kardinaliteten, antalet objekt i den resulterande sekvensen. Om detta inte anges antas kardinaliteten vara 1. I SQL Server stöds endast frågetecknet (?) förekomstindikator. Den ? indikerar att Expression kan returnera noll eller ett objekt. Om ? förekomstindikator anges returnerar instance of Sant när Expression-typen matchar den angivna SequenceType, oavsett om Expression returnerar en singleton eller en tom sekvens.

Om ? förekomstindikatorn har inte angetts returnerar sequence of endast Sant när Expression-typen matchar den angivna Type och Expression returnerar en singleton.

Obs Plussymbolen (+) och förekomstindikatorerna asterisk (*) stöds inte i SQL Server.

Följande exempel illustrerar användningen av-instansen av XQuery-operatorn.

Exempel A

I följande exempel skapas en xml- typvariabel och anger en fråga mot den. Frågeuttrycket anger en instance of operator för att avgöra om den dynamiska typen av värdet som returneras av den första operanden matchar den typ som anges i den andra operanden.

Följande fråga returnerar True eftersom värdet 125 är en instans av den angivna typen xs:heltal:

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

Följande fråga returnerar True eftersom värdet som returneras av uttrycket /a[1] i den första operanden är ett element:

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

På samma sätt returnerar instance of Sant i följande fråga, eftersom värdetypen för uttrycket i det första uttrycket är ett attribut:

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

I följande exempel returnerar uttrycket data(/a[1]ett atomiskt värde som skrivs som xdt:untypedAtomic. Därför returnerar instance of True.

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

I följande fråga returnerar uttrycket, data(/a[1]/@attrA, ett otypat atomiskt värde. Därför returnerar instance of True.

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

Exempel B

I det här exemplet kör du frågor mot en typinskriven XML-kolumn i AdventureWorks-exempeldatabasen. XML-schemasamlingen som är associerad med kolumnen som efterfrågas innehåller skrivinformationen.

I uttrycket returnerar data() det typerade värdet för attributet ProductModelID vars typ är xs:string enligt schemat som är associerat med kolumnen. Därför returnerar instance of True.

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  

Mer information finns i Compare Typed XML to Untyped XML.

Följande frågor använder det booleska instance of-uttrycket för att avgöra om attributet LocationID är av xs:heltalstyp:

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  

Följande fråga anges mot xml-kolumnen CatalogDescription. XML-schemasamlingen som är associerad med den här kolumnen innehåller skrivinformation.

Frågan använder element(ElementName, ElementType?) test i instance of-uttrycket för att verifiera att /PD:ProductDescription[1] returnerar en elementnod med ett specifikt namn och en viss typ.

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  

Frågan returnerar True.

Exempel C

När du använder unionstyper har instance of-uttrycket i SQL Server en begränsning: När typen av ett element eller attribut är en unionstyp kanske instance of kanske inte avgör den exakta typen. Därför returnerar en fråga False, såvida inte de atomiska typer som används i SequenceType är den högsta överordnade av den faktiska typen av uttryck i simpleType-hierarkin. De atomiska typer som anges i SequenceType måste alltså vara ett direkt underordnat till anySimpleType. Information om typhierarkin finns i Type Casting Rules in XQuery.

I nästa frågeexempel utförs följande:

  • Skapa en XML-schemasamling med en unionstyp, till exempel ett heltal eller en strängtyp som definierats i den.

  • Deklarera en skriven xml- variabel med hjälp av XML-schemasamlingen.

  • Tilldela variabeln en XML-exempelinstans.

  • Fråga variabeln för att illustrera instance of beteende när du hanterar en unionstyp.

Det här är frågan:

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  

Följande fråga returnerar False eftersom SequenceType som anges i instance of-uttrycket inte är den högsta överordnade av den faktiska typen av det angivna uttrycket. Värdet för <TestElement> är alltså en heltalstyp. Den högsta överordnade är xs:decimal. Den anges dock inte som den andra operanden till instance of operatorn.

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  

Eftersom det högsta överordnade värdet för xs:integer är xs:decimal returnerar frågan Sant om du ändrar frågan och anger xs:decimal som SequenceType i frågan.

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  

Exempel D

I det här exemplet skapar du först en XML-schemasamling och använder den för att skriva en xml- variabel. Den inskrivna xml--variabeln efterfrågas sedan för att illustrera instance of funktioner.

Följande XML-schemasamling definierar en enkel typ, myType, och ett element, <root>, av typen 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  

Skapa nu en skriven xml- variabel och fråga den:

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  

Eftersom myType-typen härleds av en begränsning från en varchar-typ som definieras i sqltypes-schemat returnerar instance of också True.

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  

Exempel E

I följande exempel hämtar uttrycket ett av värdena för IDREFS-attributet och använder instance of för att avgöra om värdet är av IDREF-typ. Exemplet utför följande:

  • Skapar en XML-schemasamling där <Customer>-elementet har ett OrderList- IDREFS-typattribut och <Order>-elementet har ett OrderID- ID-typattribut.

  • Skapar en skriven XML- variabel och tilldelar en XML-exempelinstans till den.

  • Anger en fråga mot variabeln. Frågeuttrycket hämtar det första order-ID-värdet från attributet OrderList IDREFS-typ för den första <Customer>. Värdet som hämtas är IDREF-typ. Därför returnerar instance of True.

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  

Implementeringsbegränsningar

Det här är begränsningarna:

  • schema-element() och schema-attribute() sekvenstyper stöds inte för jämförelse med operatorn instance of.

  • Fullständiga sekvenser, till exempel (1,2) instance of xs:integer*, stöds inte.

  • När du använder en form av element() sekvenstyp som anger ett typnamn, till exempel element(ElementName, TypeName), måste typen vara kvalificerad med ett frågetecken (?). Till exempel anger element(Title, xs:string?) att elementet kan vara null. SQL Server stöder inte körningsidentifiering av egenskapen xsi:nil med hjälp av instance of.

  • Om värdet i Expression kommer från ett element eller attribut som skrivs som en union, kan SQL Server bara identifiera den primitiva, inte härledda, typen som värdets typ härleddes från. Om <e1> till exempel har definierats för att ha en statisk typ av (xs:heltal | xs:string) returnerar följande False.

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

    Men data(<e1>123</e1>) instance of xs:decimal returnerar True.

  • För processing-instruction() och document-node() sekvenstyper tillåts endast formulär utan argument. Till exempel tillåts processing-instruction(), men processing-instruction('abc') tillåts inte.

gjuten som operator

Det som uttryck kan användas för att konvertera ett värde till en viss datatyp. Till exempel:

  
Expression cast as  AtomicType?  

I SQL Server krävs frågetecknet (?) efter AtomicType. Som du ser i följande fråga konverterar "2" cast as xs:integer? till exempel strängvärdet till ett heltal:

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

I följande fråga returnerar data() det angivna värdet för attributet ProductModelID, en strängtyp. Operatorn cast askonverterar värdet till xs:heltal.

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  

Explicit användning av data() krävs inte i den här frågan. Uttrycket cast as utför implicit atomisering på indatauttrycket.

Konstruktorfunktioner

Du kan använda konstruktorfunktioner av atomtyp. I stället för att till exempel använda operatorn cast as kan du "2" cast as xs:integer?använda funktionen xs:integer() konstruktor, som i följande exempel:

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

I följande exempel returneras ett xs:date-värde som är lika med 2000-01-01Z.

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

Du kan också använda konstruktorer för de användardefinierade atomiska typerna. Om xml-schemasamlingen som är associerad med XML-datatypen till exempel definierar en enkel typ kan en myType() konstruktor användas för att returnera ett värde av den typen.

Implementeringsbegränsningar

  • XQuery-uttrycken typeswitch, castableoch treat stöds inte.

  • som kräver ett frågetecken (?) efter atomtypen.

  • xs:QName stöds inte som typ för gjutning. Använd expanded-QName i stället.

  • xs:date, xs:timeoch xs:datetime kräver en tidszon som anges av en Z.

    Följande fråga misslyckas eftersom tidszonen inte har angetts.

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

    Genom att lägga till Z-tidszonsindikatorn i värdet fungerar frågan.

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

    Det här är resultatet:

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

Se även

XQuery-uttryck
Type System (XQuery)