Delen via


Padexpressies - Predicaten opgeven

Van toepassing op:SQL Server

Zoals beschreven in het onderwerp , bevat padexpressies in XQuery een asstap in een padexpressie de volgende onderdelen:

Het optionele predicaat is het derde deel van de asstap in een padexpressie.

Predikaten

Een predicaat wordt gebruikt om een knooppuntreeks te filteren door een opgegeven test toe te passen. De predicaatexpressie bevindt zich tussen een vierkante haak en is gebonden aan het laatste knooppunt in een padexpressie.

Stel dat een SQL-parameterwaarde (x) van het XML-gegevenstype wordt gedeclareerd, zoals wordt weergegeven in het volgende:

declare @x xml  
set @x = '  
<People>  
  <Person>  
    <Name>John</Name>  
    <Age>24</Age>  
  </Person>  
  <Person>  
    <Name>Goofy</Name>  
    <Age>54</Age>  
  </Person>  
  <Person>  
    <Name>Daffy</Name>  
    <Age>30</Age>  
  </Person>  
</People>  
'  

In dit geval zijn de volgende geldige expressies die een predicaatwaarde van [1] gebruiken op elk van drie verschillende knooppuntniveaus:

select @x.query('/People/Person/Name[1]')  
select @x.query('/People/Person[1]/Name')  
select @x.query('/People[1]/Person/Name')  

In elk geval wordt het predicaat gekoppeld aan het knooppunt in de padexpressie waarop het wordt toegepast. De eerste padexpressie selecteert bijvoorbeeld het eerste <Name> element binnen elk /People/Person-knooppunt en retourneert met het opgegeven XML-exemplaar het volgende:

<Name>John</Name><Name>Goofy</Name><Name>Daffy</Name>  

De tweede padexpressie selecteert echter alle <Name> elementen die zich onder het eerste knooppunt /Personen/Persoon bevinden. Het retourneert daarom het volgende:

<Name>John</Name>  

Haakjes kunnen ook worden gebruikt om de volgorde van evaluatie van het predicaat te wijzigen. In de volgende expressie wordt bijvoorbeeld een set haakjes gebruikt om het pad van (/Personen/Persoon/Naam) van het predicaat [1] te scheiden:

select @x.query('(/People/Person/Name)[1]')  

In dit voorbeeld wordt de volgorde waarin het predicaat wordt toegepast, gewijzigd. Dit komt doordat het ingesloten pad eerst wordt geëvalueerd (/People/Person/Name) en vervolgens wordt de predicaat [1] operator toegepast op de set die alle knooppunten bevat die overeenkomen met het ingesloten pad. Zonder de haakjes is de volgorde van de bewerking anders als de [1] wordt toegepast als een child::Name knooppunttest, vergelijkbaar met het eerste voorbeeld van de padexpressie.

Kwantificatoren en predicaten

Kwantificatoren kunnen meer dan één keer worden gebruikt en toegevoegd binnen de accolades van het predicaat zelf. In het vorige voorbeeld is het volgende bijvoorbeeld een geldig gebruik van meer dan één kwantificator binnen een complexe predicaatsubexpressie.

select @x.query('/People/Person[contains(Name[1], "J") and xs:integer(Age[1]) < 40]/Name/text()')  

Het resultaat van een predicaatexpressie wordt geconverteerd naar een Booleaanse waarde en wordt aangeduid als de predicaat waarheidswaarde. Alleen de knooppunten in de volgorde waarvoor de predicaat waarheidswaarde Waar is, worden in het resultaat geretourneerd. Alle andere knooppunten worden verwijderd.

De volgende padexpressie bevat bijvoorbeeld een predicaat in de tweede stap:

/child::root/child::Location[attribute::LocationID=10]  

De voorwaarde die door dit predicaat wordt opgegeven, wordt toegepast op alle <Location> onderliggende elementknooppunten. Het resultaat is dat alleen de locaties van het werkcentrum waarvan de waarde van het locationID-kenmerk 10 is, worden geretourneerd.

De vorige padexpressie wordt uitgevoerd in de volgende SELECT-instructie:

SELECT Instructions.query('  
declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
 /child::AWMI:root/child::AWMI:Location[attribute::LocationID=10]  
')  
FROM Production.ProductModel  
WHERE ProductModelID=7  

Rekenpredicate Waarheidswaarden

De volgende regels worden toegepast om de predicaat waarheidswaarde te bepalen, volgens de XQuery-specificaties:

  1. Als de waarde van de predicaatexpressie een lege reeks is, is de predicaat waarheidswaarde Onwaar.

    Voorbeeld:

    SELECT Instructions.query('  
    declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
     /child::AWMI:root/child::AWMI:Location[attribute::LotSize]  
    ')  
    FROM Production.ProductModel  
    WHERE ProductModelID=7  
    

    De padexpressie in deze query retourneert alleen de <Location> elementknooppunten waarvoor een LotSize-kenmerk is opgegeven. Als het predicaat een lege reeks voor een specifieke <Location>waarde retourneert, wordt die locatie van het werkcentrum niet geretourneerd in het resultaat.

  2. Predicaatwaarden kunnen alleen xs:integer, xs:Booleaanse waarde of knooppunt* zijn. Voor knooppunt*resulteert het predicaat in Waar als er knooppunten zijn en Onwaar voor een lege reeks. Elk ander numeriek type, zoals dubbel- en floattype, genereert een statische typefout. De predicaat waarheidswaarde van een expressie is Waar als en alleen als het resulterende gehele getal gelijk is aan de waarde van de contextpositie. Bovendien verminderen alleen letterlijke waarden voor gehele getallen en de laatste() functie de kardinaliteit van de gefilterde stapexpressie tot 1.

    Met de volgende query wordt bijvoorbeeld het derde onderliggende elementknooppunt van het <Features> element opgehaald.

    SELECT CatalogDescription.query('  
    declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
    declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
     /child::PD:ProductDescription/child::PD:Features/child::*[3]  
    ')  
    FROM Production.ProductModel  
    WHERE ProductModelID=19  
    

    Let op het volgende uit de vorige query:

    • De derde stap in de expressie geeft een predicaatexpressie op waarvan de waarde 3 is. Daarom is de predicaat waarheidswaarde van deze expressie alleen waar voor de knooppunten waarvan de contextpositie 3 is.

    • In de derde stap wordt ook een jokerteken (*) opgegeven dat alle knooppunten in de knooppunttest aangeeft. Het predicaat filtert echter de knooppunten en retourneert alleen het knooppunt op de derde positie.

    • De query retourneert het derde onderliggende elementknooppunt van het <Features> element onderliggende elementen van het element onderliggende elementen van de <ProductDescription> hoofdmap van het document.

  3. Als de waarde van de predicaatexpressie één eenvoudige typewaarde van het type Booleaanse waarde is, is de predicaat waarheidswaarde gelijk aan de waarde van de predicaatexpressie.

    De volgende query wordt bijvoorbeeld opgegeven op basis van een XML-typevariabele die een XML-exemplaar bevat, het XML-exemplaar van de klantenquête. Met de query worden klanten opgehaald die kinderen hebben. In deze query zou dat HasChildren 1</HasChildren>< zijn>.

    declare @x xml  
    set @x='  
    <Survey>  
      <Customer CustomerID="1" >  
      <Age>27</Age>  
      <Income>20000</Income>  
      <HasChildren>1</HasChildren>  
      </Customer>  
      <Customer CustomerID="2" >  
      <Age>27</Age>  
      <Income>20000</Income>  
      <HasChildren>0</HasChildren>  
      </Customer>  
    </Survey>  
    '  
    declare @y xml  
    set @y = @x.query('  
      for $c in /child::Survey/child::Customer[( child::HasChildren[1] cast as xs:boolean ? )]  
      return   
          <CustomerWithChildren>  
              { $c/attribute::CustomerID }  
          </CustomerWithChildren>  
    ')  
    select @y  
    

    Let op het volgende uit de vorige query:

    • De expressie in de for-lus heeft twee stappen en de tweede stap geeft een predicaat op. De waarde van dit predicaat is een Booleaanse typewaarde. Als deze waarde Waar is, is de waarheidswaarde van het predicaat ook Waar.

    • De query retourneert de onderliggende elementen van het element, waarvan de <Customer> predicaatwaarde Waar is, van het <onderliggende element Enquête> van de hoofdmap van het document. Dit is het resultaat:

      <CustomerWithChildren CustomerID="1"/>   
      
  4. Als de waarde van de predicaatexpressie een reeks is die ten minste één knooppunt bevat, is de predicaat waarheidswaarde Waar.

Met de volgende query wordt bijvoorbeeld ProductModelID opgehaald voor productmodellen waarvan de beschrijving van de XML-catalogus ten minste één functie, een onderliggend element van het <Features> element, bevat uit de naamruimte die is gekoppeld aan het wm-voorvoegsel .

SELECT ProductModelID  
FROM   Production.ProductModel  
WHERE CatalogDescription.exist('  
             declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
             declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
             /child::PD:ProductDescription/child::PD:Features[wm:*]  
             ') = 1  

Let op het volgende uit de vorige query:

  • Met de WHERE-component wordt de methode exist() (XML-gegevenstype) opgegeven.

  • De padexpressie in de methode exist() geeft een predicaat op in de tweede stap. Als de predicaatexpressie een reeks van ten minste één functie retourneert, is de waarheidswaarde van deze predicaatexpressie Waar. Omdat de methode exist() in dit geval een True retourneert, wordt de ProductModelID geretourneerd.

Statische typen en predicaatfilters

De predicaten kunnen ook van invloed zijn op het statisch uitgestelde type expressie. Letterlijke waarden voor gehele getallen en de laatste() functie verminderen de kardinaliteit van de gefilterde stapexpressie tot maximaal één.