Share via


Algemene XQuery-gebruiksvoorbeelden

van toepassing op:SQL Server-

Dit artikel bevat algemene voorbeelden van XQuery-gebruik.

Voorbeelden

Een. Querycatalogusbeschrijvingen om producten en gewichten te vinden

De volgende query retourneert de productmodel-id's en gewichten, indien aanwezig, uit de productcatalogusbeschrijving. Met de query wordt XML samengesteld die het volgende formulier heeft:

<Product ProductModelID="...">
  <Weight>...</Weight>
</Product>

Dit is de query:

SELECT CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
  <Product  ProductModelID="{ (/p1:ProductDescription/@ProductModelID)[1] }">
     {
       /p1:ProductDescription/p1:Specifications/Weight
     }
  </Product>
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL;

Let op de volgende overwegingen uit de vorige query:

  • Het namespace trefwoord in het XQuery-prolog definieert een naamruimtevoorvoegsel dat wordt gebruikt in de hoofdtekst van de query.

  • De hoofdtekst van de query maakt de vereiste XML.

  • In de WHERE component wordt de exist() methode gebruikt om alleen rijen te vinden die productcatalogusbeschrijvingen bevatten. Dat wil gezegd, de XML die het <ProductDescription> element bevat.

Dit is het resultaat:

<Product ProductModelID="19"/>
<Product ProductModelID="23"/>
<Product ProductModelID="25"/>
<Product ProductModelID="28"><Weight>Varies with size.</Weight></Product>
<Product ProductModelID="34"/>
<Product ProductModelID="35"/>

De volgende query haalt dezelfde informatie op, maar alleen voor die productmodellen waarvan de catalogusbeschrijving het gewicht, het <Weight> element, in de specificaties, het <Specifications> element bevat. In dit voorbeeld wordt het WITH XMLNAMESPACES voorvoegsel en de pd bijbehorende naamruimtebinding gede declareren. Op deze manier wordt de binding niet beschreven in zowel de query() methode als in de exist() methode.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT CatalogDescription.query('
          <Product  ProductModelID="{ (/pd:ProductDescription/@ProductModelID)[1] }">
                 {
                      /pd:ProductDescription/pd:Specifications/Weight
                 }
          </Product>
') AS x
FROM Production.ProductModel
WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Specifications//Weight ') = 1;

In de vorige query controleert de exist() methode van het XML-gegevenstype in de WHERE component of er een <Weight> element in het <Specifications> element is.

B. Productmodel-id's zoeken voor productmodellen waarvan de catalogusbeschrijvingen front-angle en kleine afbeeldingen bevatten

De beschrijving van de XML-productcatalogus bevat de productafbeeldingen, het <Picture> element. Elke afbeelding heeft verschillende eigenschappen, waaronder de afbeeldingshoek (het <Angle> element) en de grootte (het <Size> element).

Voor productmodellen waarvan de catalogusbeschrijvingen front-angle en kleine afbeeldingen bevatten, maakt de query XML met de volgende vorm:

< Product ProductModelID="...">
  <Picture>
    <Angle>front</Angle>
    <Size>small</Size>
  </Picture>
</Product>
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT CatalogDescription.query('
   <pd:Product  ProductModelID="{ (/pd:ProductDescription/@ProductModelID)[1] }">
      <Picture>
         {  /pd:ProductDescription/pd:Picture/pd:Angle }
         {  /pd:ProductDescription/pd:Picture/pd:Size }
      </Picture>
   </pd:Product>
') as Result
FROM  Production.ProductModel
WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Picture') = 1
AND   CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Angle)[1]', 'varchar(20)')  = 'front'
AND   CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Size)[1]', 'varchar(20)')  = 'small'

Let op de volgende overwegingen uit de vorige query:

  • In de WHERE component wordt de exist() methode gebruikt om alleen rijen met productcatalogusbeschrijvingen met het <Picture> element op te halen.

  • De WHERE component gebruikt de value() methode twee keer om de waarden van de <Size> en <Angle> elementen te vergelijken.

Dit is een gedeeltelijk resultaat:

<p1:Product
  xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"
  ProductModelID="19">
  <Picture>
    <p1:Angle>front</p1:Angle>
    <p1:Size>small</p1:Size>
  </Picture>
</p1:Product>
...

C. Maak een platte lijst met de naam en functieparen van het productmodel, waarbij elk paar in het <onderdelen> element wordt geplaatst

In de beschrijving van de productmodelcatalogus bevat de XML verschillende productfuncties. Al deze functies zijn opgenomen in het <Features> element. De query maakt gebruik van XML-constructie (XQuery) om de vereiste XML samen te stellen. De expressie in de accolades wordt vervangen door het resultaat.

SELECT CatalogDescription.query('
declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
  for $pd in /p1:ProductDescription,
   $f in $pd/p1:Features/*
  return
   <Feature>
     <ProductModelName> { data($pd/@ProductModelName) } </ProductModelName>
     { $f }
  </Feature>
') AS x
FROM Production.ProductModel
WHERE ProductModelID = 19;

Let op de volgende overwegingen uit de vorige query:

  • $pd/p1:Features/* retourneert alleen de onderliggende elementen van <Features>het elementknooppunt, maar $pd/p1:Features/node() retourneert alle knooppunten. Dit omvat de elementknooppunten, tekstknooppunten, verwerkingsinstructies en opmerkingen.

  • De twee FOR lussen genereren een Cartesisch product waarvan de productnaam en de afzonderlijke functie worden geretourneerd.

  • Het ProductName is een kenmerk. De XML-constructie in deze query retourneert deze als een element.

Dit is een gedeeltelijk resultaat:

<Feature>
 <ProductModelName>Mountain 100</ProductModelName>
 <ProductModelID>19</ProductModelID>
 <p1:Warranty
   xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
    <p1:WarrantyPeriod>3 year</p1:WarrantyPeriod>
    <p1:Description>parts and labor</p1:Description>
 </p1:Warranty>
</Feature>
<Feature>
 <ProductModelName>Mountain 100</ProductModelName>
 <ProductModelID>19</ProductModelID>
 <p2:Maintenance xmlns:p2="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
    <p2:NoOfYears>10</p2:NoOfYears>
    <p2:Description>maintenance contact available through your dealer
           or any AdventureWorks retail store.</p2:Description>
    </p2:Maintenance>
</Feature>
...
...

D. Vermeld in de catalogusbeschrijving van een productmodel de naam van het productmodel, de model-id en de functies die zijn gegroepeerd in een <Product>-element

Met behulp van de informatie die is opgeslagen in de catalogusbeschrijving van het productmodel, bevat de volgende query de naam van het productmodel, de model-id en de functies die in een <Product> element zijn gegroepeerd.

SELECT ProductModelID,
       CatalogDescription.query('
     declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     <Product>
         <ProductModelName>
           { data(/pd:ProductDescription/@ProductModelName) }
         </ProductModelName>
         <ProductModelID>
           { data(/pd:ProductDescription/@ProductModelID) }
         </ProductModelID>
         { /pd:ProductDescription/pd:Features/* }
     </Product>
') AS x
FROM Production.ProductModel
WHERE ProductModelID = 19;

Dit is een gedeeltelijk resultaat:

<Product>
  <ProductModelName>Mountain 100</ProductModelName>
  <ProductModelID>19</ProductModelID>
  <p1:Warranty>... </p1:Warranty>
  <p2:Maintenance>...  </p2:Maintenance>
  <p3:wheel xmlns:p3="https://www.adventure-works.com/schemas/OtherFeatures">High performance wheels.</p3:wheel>
  <p4:saddle xmlns:p4="https://www.adventure-works.com/schemas/OtherFeatures">
    <p5:i xmlns:p5="http://www.w3.org/1999/xhtml">Anatomic design</p5:i> and made from durable leather for a full-day of riding in comfort.</p4:saddle>
  <p6:pedal xmlns:p6="https://www.adventure-works.com/schemas/OtherFeatures">
    <p7:b xmlns:p7="http://www.w3.org/1999/xhtml">Top-of-the-line</p7:b> clipless pedals with adjustable tension.</p6:pedal>
   ...

E. Beschrijvingen van productmodelfuncties ophalen

Met de volgende query wordt XML samengesteld die een <Product> element bevat ProductModelIDmet kenmerken ProductModelName en de eerste twee productfuncties. De eerste twee productfuncties zijn met name de eerste twee onderliggende elementen van het <Features> element. Als er meer functies zijn, wordt er een leeg <There-is-more/> element geretourneerd.

SELECT CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     <Product>
          { /pd:ProductDescription/@ProductModelID }
          { /pd:ProductDescription/@ProductModelName }
          {
            for $f in /pd:ProductDescription/pd:Features/*[position()<=2]
            return
            $f
          }
          {
            if (count(/pd:ProductDescription/pd:Features/*) > 2)
            then <there-is-more/>
            else ()
          }
     </Product>
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL;

Let op de volgende overwegingen uit de vorige query:

  • De FOR structuur van de ... RETURN lus haalt de eerste twee productfuncties op. De position() functie wordt gebruikt om de positie van de elementen in de reeks te bepalen.

F. Elementnamen zoeken uit de beschrijving van de productcatalogus die eindigen op ons

De volgende query doorzoekt de catalogusbeschrijvingen en retourneert alle elementen in het element waarvan de <ProductDescription> naam eindigt op ons.

SELECT ProductModelID,
       CatalogDescription.query('
     declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
      for $pd in /p1:ProductDescription/*[substring(local-name(.),string-length(local-name(.))-2,3)="ons"]
      return
          <Root>
             { $pd }
          </Root>
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL;

Dit is een gedeeltelijk resultaat:

ProductModelID   Result
-----------------------------------------
         19        <Root>
                     <p1:Specifications xmlns:p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
                          ...
                     </p1:Specifications>
                   </Root>

G. Overzichtsbeschrijvingen zoeken die het woord "Aerodynamisch" bevatten

Met de volgende query worden productmodellen opgehaald waarvan de catalogusbeschrijvingen het woord 'Aerodynamisch' bevatten in de samenvattingsbeschrijving:

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd)
SELECT ProductModelID,
       CatalogDescription.query('
          <Prod >
             { /pd:ProductDescription/@ProductModelID }
             { /pd:ProductDescription/pd:Summary }
          </Prod>
 ') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.value('
     contains( string( (/pd:ProductDescription/pd:Summary)[1] ),"Aerodynamic")', 'bit') = 1;

De SELECT query specificeert query() en value() methoden van het XML-gegevenstype . Daarom wordt het voorvoegsel pd in de query gebruikt in plaats van de declaratie van de naamruimten twee keer te herhalen in twee verschilquery's en wordt het slechts eenmaal gedefinieerd met behulp van WITH XMLNAMESPACES.

Let op de volgende overwegingen uit de vorige query:

  • De WHERE component wordt gebruikt om alleen de rijen op te halen waarin de catalogusbeschrijving het woord 'Aerodynamisch' in het <Summary> element bevat.

  • De contains() functie wordt gebruikt om te zien of het woord is opgenomen in de tekst.

  • De value() methode van het XML-gegevenstype vergelijkt de waarde die wordt geretourneerd door contains() 1.

Dit is het resultaat:

ProductModelID Result
-------------- ------------------------------------------
28     <Prod ProductModelID="28">
        <pd:Summary xmlns:pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription">
       <p1:p xmlns:p1="http://www.w3.org/1999/xhtml">
         A TRUE multi-sport bike that offers streamlined riding and a
         revolutionary design. Aerodynamic design lets you ride with the
         pros, and the gearing will conquer hilly roads.</p1:p>
       </pd:Summary>
      </Prod>

H. Productmodellen zoeken waarvan catalogusbeschrijvingen geen productmodelafbeeldingen bevatten

Met de volgende query worden ProductModelIDs opgehaald voor productmodellen waarvan de catalogusbeschrijvingen geen element bevatten <Picture> .

SELECT ProductModelID
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL
      AND CatalogDescription.exist('declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     /p1:ProductDescription/p1:Picture
') = 0;

Let op de volgende overwegingen uit de vorige query:

  • Als de exist() methode in de WHERE component False (0) retourneert, wordt de productmodel-id geretourneerd. Anders wordt het niet geretourneerd.

  • Omdat alle productbeschrijvingen een <Picture> element bevatten, is de resultatenset in dit geval leeg.