Delen via


TypeSysteem - Reekstypekoppeling

van toepassing op:SQL Server-

Een XQuery-expressiewaarde is altijd een reeks nul of meer items. Een item kan een atomische waarde of een knooppunt zijn. Het reekstype verwijst naar de mogelijkheid om het reekstype te vinden dat wordt geretourneerd door een query-expressie met een specifiek type. Bijvoorbeeld:

  • Als de expressiewaarde atomisch is, wilt u mogelijk weten of het een geheel getal, decimaal of tekenreekstype is.

  • Als de expressiewaarde een XML-knooppunt is, wilt u misschien weten of het een opmerkingknooppunt, een verwerkingsinstructieknooppunt of een tekstknooppunt is.

  • Mogelijk wilt u weten of de expressie een XML-element of een kenmerkknooppunt van een specifieke naam en type retourneert.

U kunt de instance of Booleaanse operator gebruiken in reekstypekoppeling. Zie SequenceType Expressions (XQuery)voor meer informatie over de instance of-expressie.

Het type atomische waarde vergelijken dat wordt geretourneerd door een expressie

Als een expressie een reeks atomische waarden retourneert, moet u mogelijk het type van de waarde in de reeks vinden. In de volgende voorbeelden ziet u hoe syntaxis van het reekstype kan worden gebruikt om het atomische waardetype te evalueren dat wordt geretourneerd door een expressie.

Voorbeeld: Bepalen of een reeks leeg is

Het lege() reekstype kan worden gebruikt in een reekstypeexpressie om te bepalen of de reeks die wordt geretourneerd door de opgegeven expressie een lege reeks is.

In het volgende voorbeeld kan het XML-schema het <root> element nilled zijn:

CREATE XML SCHEMA COLLECTION SC AS N'  
<schema xmlns="http://www.w3.org/2001/XMLSchema">  
      <element name="root" nillable="true" type="byte"/>  
</schema>'  
GO  

Als een getypt XML-exemplaar nu een waarde voor het <root> element opgeeft, retourneert instance of empty() False.

DECLARE @var XML(SC1)  
SET @var = '<root>1</root>'  
-- The following returns False  
SELECT @var.query('data(/root[1]) instance of  empty() ')  
GO  

Als het <root> element in het exemplaar is geïmpleerd, is de waarde ervan een lege reeks en retourneert de instance of empty() Waar.

DECLARE @var XML(SC)  
SET @var = '<root xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />'  
SELECT @var.query('data(/root[1]) instance of  empty() ')  
GO  

Voorbeeld: Het type kenmerkwaarde bepalen

Soms wilt u het reekstype evalueren dat wordt geretourneerd door een expressie voordat u deze verwerkt. U hebt bijvoorbeeld een XML-schema waarin een knooppunt is gedefinieerd als samenvoegingstype. In het volgende voorbeeld definieert het XML-schema in de verzameling het kenmerk a als een samenvoegtype waarvan de waarde een decimaal of tekenreekstype kan zijn.

-- Drop schema collection if it exists.  
-- DROP XML SCHEMA COLLECTION SC.  
-- GO  
CREATE XML SCHEMA COLLECTION SC AS N'  
<schema xmlns="http://www.w3.org/2001/XMLSchema">  
  <element name="root">  
    <complexType>  
       <sequence/>  
         <attribute name="a">  
            <simpleType>  
               <union memberTypes="decimal string"/>  
            </simpleType>  
         </attribute>  
     </complexType>  
  </element>  
</schema>'  
GO  

Voordat u een getypt XML-exemplaar verwerkt, wilt u mogelijk weten welk type kenmerk a waarde. In het volgende voorbeeld is het kenmerk a waarde een decimaal type. Daarom retourneert, instance of xs:decimal Waar.

DECLARE @var XML(SC)  
SET @var = '<root a="2.5"/>'  
SELECT @var.query('data((/root/@a)[1]) instance of xs:decimal')  
GO  

Wijzig nu het kenmerk a waarde in een tekenreekstype. De instance of xs:string retourneert Waar.

DECLARE @var XML(SC)  
SET @var = '<root a="Hello"/>'  
SELECT @var.query('data((/root/@a)[1]) instance of xs:string')  
GO  

Voorbeeld: Kardinaliteit in reeksexpressies

In dit voorbeeld ziet u het effect van kardinaliteit in een reeksexpressie. In het volgende XML-schema wordt een <root> element gedefinieerd dat van het bytetype is en niet kan worden gebruikt.

CREATE XML SCHEMA COLLECTION SC AS N'  
<schema xmlns="http://www.w3.org/2001/XMLSchema">  
      <element name="root" nillable="true" type="byte"/>  
</schema>'  
GO  

In de volgende query, omdat de expressie een singleton van het bytetype retourneert, retourneert instance of Waar.

DECLARE @var XML(SC)  
SET @var = '<root>111</root>'  
SELECT @var.query('data(/root[1]) instance of  xs:byte ')   
GO  

Als u het <root> element nul maakt, is de waarde een lege reeks. Dat wil gezegd: de expressie, /root[1], retourneert een lege reeks. Daarom retourneert instance of xs:byte False. Houd er rekening mee dat de standaardkardinaliteit in dit geval 1 is.

DECLARE @var XML(SC)  
SET @var = '<root xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></root>'  
SELECT @var.query('data(/root[1]) instance of  xs:byte ')   
GO  
-- result = false  

Als u kardinaliteit opgeeft door de exemplaarindicator (?) toe te voegen, retourneert de reeksexpressie True.

DECLARE @var XML(SC)  
SET @var = '<root xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></root>'  
SELECT @var.query('data(/root[1]) instance of  xs:byte? ')   
GO  
-- result = true  

Houd er rekening mee dat het testen in een expressie voor een reekstype in twee fasen is voltooid:

  1. Eerst bepaalt de test of het expressietype overeenkomt met het opgegeven type.

  2. Als dit het geval is, bepaalt de test of het aantal items dat door de expressie wordt geretourneerd overeenkomt met de opgegeven exemplaarindicator.

Als beide waar zijn, retourneert de instance of expressie Waar.

Voorbeeld: Query's uitvoeren op een xml-typekolom

In het volgende voorbeeld wordt een query opgegeven op basis van een kolom Instructies van xml- in de AdventureWorks2022-database. Het is een getypte XML-kolom omdat er een schema aan is gekoppeld. Het XML-schema definieert het kenmerk LocationID van het type geheel getal. Daarom retourneert de instance of xs:integer? in de reeksexpressie Waar.

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

Het knooppunttype vergelijken dat wordt geretourneerd door een expressie

Als een expressie een reeks knooppunten retourneert, moet u mogelijk het type van het knooppunt in de reeks vinden. In de volgende voorbeelden ziet u hoe syntaxis van het reekstype kan worden gebruikt om het knooppunttype te evalueren dat wordt geretourneerd door een expressie. U kunt de volgende reekstypen gebruiken:

  • item() - komt overeen met een item in de reeks.

  • node() - Bepaalt of de reeks een knooppunt is.

  • verwerkingsinstructie() - Bepaalt of de expressie een verwerkingsinstructie retourneert.

  • comment() - Bepaalt of de expressie een opmerking retourneert.

  • documentknooppunt() - Bepaalt of de expressie een documentknooppunt retourneert.

In het volgende voorbeeld ziet u deze reekstypen.

Voorbeeld: Reekstypen gebruiken

In dit voorbeeld worden verschillende query's uitgevoerd op een niet-getypte XML-variabele. Deze query's illustreren het gebruik van reekstypen.

DECLARE @var XML  
SET @var = '<?xml-stylesheet href="someValue" type="text/xsl" ?>  
<root>text node  
  <!-- comment 1 -->   
  <a>Data a</a>  
  <!-- comment  2 -->  
</root>'  

In de eerste query retourneert de expressie de getypte waarde van het element <a>. In de tweede query retourneert de expressie het element <a>. Beide zijn items. Daarom retourneren beide query's Waar.

SELECT @var.query('data(/root[1]/a[1]) instance of item()')  
SELECT @var.query('/root[1]/a[1] instance of item()')  

Alle XQuery-expressies in de volgende drie query's retourneren het elementknooppunt onderliggende element van het <root>-element. Daarom retourneert de expressie van het reekstype, instance of node(), Waar en de andere twee expressies, instance of text() en instance of document-node(), onwaar.

SELECT @var.query('(/root/*)[1] instance of node()')  
SELECT @var.query('(/root/*)[1] instance of text()')  
SELECT @var.query('(/root/*)[1] instance of document-node()')   

In de volgende query retourneert de instance of document-node()-expressie Waar, omdat het bovenliggende element van het <root> element een documentknooppunt is.

SELECT @var.query('(/root/..)[1] instance of document-node()') -- true  

In de volgende query haalt de expressie het eerste knooppunt op uit het XML-exemplaar. Omdat het een verwerkingsinstructieknooppunt is, retourneert de instance of processing-instruction() expressie Waar.

SELECT @var.query('(/node())[1] instance of processing-instruction()')  

Implementatiebeperkingen

Dit zijn de specifieke beperkingen:

  • documentknooppunt() met syntaxis van inhoudstype wordt niet ondersteund.

  • verwerkingsinstructie(naam) syntaxis wordt niet ondersteund.

Elementtests

Er wordt een elementtest gebruikt om het elementknooppunt dat wordt geretourneerd door een expressie te koppelen aan een elementknooppunt met een specifieke naam en een specifiek type. U kunt deze elementtests gebruiken:

element ()  
element(ElementName)  
element(ElementName, ElementType?)   
element(*, ElementType?)  

Kenmerktests

De kenmerktest bepaalt of het kenmerk dat wordt geretourneerd door een expressie een kenmerkknooppunt is. U kunt deze kenmerktests gebruiken.

attribute()

attribute(AttributeName)

attribute(AttributeName, AttributeType)

Testvoorbeelden

In de volgende voorbeelden ziet u scenario's waarin element- en kenmerktests nuttig zijn.

Voorbeeld A

Het volgende XML-schema definieert het CustomerType complexe type waarbij <firstName> en <lastName> elementen optioneel zijn. Voor een opgegeven XML-exemplaar moet u mogelijk bepalen of de voornaam voor een bepaalde klant bestaat.

CREATE XML SCHEMA COLLECTION SC AS N'  
<schema xmlns="http://www.w3.org/2001/XMLSchema"  
targetNamespace="myNS" xmlns:ns="myNS">  
  <complexType name="CustomerType">  
     <sequence>  
        <element name="firstName" type="string" minOccurs="0"   
                  nillable="true" />  
        <element name="lastName" type="string" minOccurs="0"/>  
     </sequence>  
  </complexType>  
  <element name="customer" type="ns:CustomerType"/>  
</schema>  
'  
GO  
DECLARE @var XML(SC)  
SET @var = '<x:customer xmlns:x="myNS">  
<firstName>SomeFirstName</firstName>  
<lastName>SomeLastName</lastName>  
</x:customer>'  

In de volgende query wordt een instance of element (firstName)-expressie gebruikt om te bepalen of het eerste onderliggende element van <customer> een element is waarvan de naam <firstName>is. In dit geval wordt True geretourneerd.

SELECT @var.query('declare namespace x="myNS";   
     (/x:customer/*)[1] instance of element (firstName)')  
GO  

Als u het <firstName> element uit het exemplaar verwijdert, retourneert de query Onwaar.

U kunt ook het volgende gebruiken:

  • De syntaxis van het element(ElementName, ElementType?) reekstype, zoals wordt weergegeven in de volgende query. Het komt overeen met een nilled of niet-nilled elementknooppunt waarvan de naam is firstName en waarvan het type is xs:string.

    SELECT @var.query('declare namespace x="myNS";   
    (/x:customer/*)[1] instance of element (firstName, xs:string?)')  
    
  • De syntaxis van het element(*, type?) reekstype, zoals wordt weergegeven in de volgende query. Het komt overeen met het elementknooppunt als het type xs:stringis, ongeacht de naam.

    SELECT @var.query('declare namespace x="myNS"; (/x:customer/*)[1] instance of element (*, xs:string?)')  
    GO  
    

Voorbeeld B

In het volgende voorbeeld ziet u hoe u kunt bepalen of het knooppunt dat wordt geretourneerd door een expressie een elementknooppunt met een specifieke naam is. Hierbij wordt de element() test gebruikt.

In het volgende voorbeeld zijn de twee <Customer> elementen in het XML-exemplaar waarop een query wordt uitgevoerd, van twee verschillende typen, CustomerType en SpecialCustomerType. Stel dat u het type van het <Customer>-element wilt weten dat door de expressie wordt geretourneerd. De volgende XML-schemaverzameling definieert de typen CustomerType en SpecialCustomerType.

CREATE XML SCHEMA COLLECTION SC AS N'  
<schema xmlns="http://www.w3.org/2001/XMLSchema"  
          targetNamespace="myNS"  xmlns:ns="myNS">  
  <complexType name="CustomerType">  
    <sequence>  
      <element name="firstName" type="string"/>  
      <element name="lastName" type="string"/>  
    </sequence>  
  </complexType>  
  <complexType name="SpecialCustomerType">  
     <complexContent>  
       <extension base="ns:CustomerType">  
        <sequence>  
            <element name="Age" type="int"/>  
        </sequence>  
       </extension>  
     </complexContent>  
    </complexType>  
   <element name="customer" type="ns:CustomerType"/>  
</schema>  
'  
GO  

Deze XML-schemaverzameling wordt gebruikt om een getypte xml- variabele te maken. Het XML-exemplaar dat aan deze variabele is toegewezen, heeft twee <customer> elementen van twee verschillende typen. Het eerste element is van CustomerType en het tweede element is van SpecialCustomerType type.

DECLARE @var XML(SC)  
SET @var = '  
<x:customer xmlns:x="myNS">  
   <firstName>FirstName1</firstName>  
   <lastName>LastName1</lastName>  
</x:customer>  
<x:customer xsi:type="x:SpecialCustomerType" xmlns:x="myNS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
   <firstName> FirstName2</firstName>  
   <lastName> LastName2</lastName>  
   <Age>21</Age>  
</x:customer>'  

In de volgende query retourneert de instance of element (*, x:SpecialCustomerType ?) expressie False, omdat de expressie het eerste klantelement retourneert dat niet van SpecialCustomerType type is.

SELECT @var.query('declare namespace x="myNS";   
    (/x:customer)[1] instance of element (*, x:SpecialCustomerType ?)')  

Als u de expressie van de vorige query wijzigt en het tweede <customer> element (/x:customer)[2]) ophaalt, retourneert de instance of Waar.

Voorbeeld C

In dit voorbeeld wordt de kenmerktest gebruikt. Het volgende XML-schema definieert het complexe type CustomerType met kenmerken CustomerID en Leeftijd. Het kenmerk Leeftijd is optioneel. Voor een specifiek XML-exemplaar kunt u bepalen of het kenmerk Leeftijd aanwezig is in het element <customer>.

CREATE XML SCHEMA COLLECTION SC AS N'  
<schema xmlns="http://www.w3.org/2001/XMLSchema"  
       targetNamespace="myNS" xmlns:ns="myNS">  
<complexType name="CustomerType">  
  <sequence>  
     <element name="firstName" type="string" minOccurs="0"   
               nillable="true" />  
     <element name="lastName" type="string" minOccurs="0"/>  
  </sequence>  
  <attribute name="CustomerID" type="integer" use="required" />  
  <attribute name="Age" type="integer" use="optional" />  
 </complexType>  
 <element name="customer" type="ns:CustomerType"/>  
</schema>  
'  
GO  

De volgende query retourneert True, omdat er een kenmerkknooppunt is waarvan de naam is Age in het XML-exemplaar waarop een query wordt uitgevoerd. De attribute(Age) kenmerktest wordt gebruikt in deze expressie. Omdat kenmerken geen volgorde hebben, gebruikt de query de FLWOR-expressie om alle kenmerken op te halen en vervolgens elk kenmerk te testen met behulp van de instance of-expressie. In het voorbeeld wordt eerst een XML-schemaverzameling gemaakt om een getypte xml- variabele te maken.

DECLARE @var XML(SC)  
SET @var = '<x:customer xmlns:x="myNS" CustomerID="1" Age="22" >  
<firstName>SomeFName</firstName>  
<lastName>SomeLName</lastName>  
</x:customer>'  
SELECT @var.query('declare namespace x="myNS";   
FOR $i in /x:customer/@*  
RETURN  
    IF ($i instance of attribute (Age)) THEN  
        "true"  
        ELSE  
        ()')     
GO  
  

Als u het optionele kenmerk Age uit het exemplaar verwijdert, retourneert de vorige query Onwaar.

U kunt de kenmerknaam en het type (attribute(name,type)) opgeven in de kenmerktest.

SELECT @var.query('declare namespace x="myNS";   
FOR $i in /x:customer/@*  
RETURN  
    IF ($i instance of attribute (Age, xs:integer)) THEN  
        "true"  
        ELSE  
        ()')  

U kunt ook de syntaxis van het attribute(*, type) reekstype opgeven. Dit komt overeen met het kenmerkknooppunt als het kenmerktype overeenkomt met het opgegeven type, ongeacht de naam.

Implementatiebeperkingen

Dit zijn de specifieke beperkingen:

  • In de elementtest moet de typenaam worden gevolgd door de exemplaarindicator (?).

  • element(ElementName, TypeName) wordt niet ondersteund.

  • element(*, TypeName) wordt niet ondersteund.

  • schema-element() wordt niet ondersteund.

  • schemakenmerk (AttributeName) wordt niet ondersteund.

  • Het expliciet opvragen van xsi:type of xsi:nil wordt niet ondersteund.

Zie ook

Type System (XQuery)