XQueries met hiërarchie

Van toepassing op:SQL Server

De meeste xml-kolommen in de AdventureWorks-database zijn semi-gestructureerde documenten. Daarom kunnen documenten die in elke rij zijn opgeslagen er anders uitzien. De voorbeelden van zoekopdrachten in dit onderwerp illustreren hoe informatie uit deze verschillende documenten te extraheren.

Examples

Eén. Uit de documenten van de productie-instructies haalt u de locaties van het werkcentrum op, samen met de eerste productiestap op die locaties

Voor product model 7 construeert de query XML die het <ManuInstr> element bevat, met attributen ProductModelID en ProductModelName, en één of meer <Location> kindelementen.

Elk <Location> element heeft zijn eigen set attributen en één <step> kindelement. Dit <step> onderelement is de eerste productiestap op de locatie van het werkcentrum.

SELECT Instructions.query('  
     declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
   \<ManuInstr  ProdModelID = "{sql:column("Production.ProductModel.ProductModelID") }"   
                ProductModelName = "{ sql:column("Production.ProductModel.Name") }" >  
            {   
              for $wc in //AWMI:root/AWMI:Location  
              return  
                <Location>  
                 {$wc/@* }  
                 <step1> { string( ($wc//AWMI:step)[1] ) } </step1>  
                </Location>  
            }  
          </ManuInstr>  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID=7  

Let op het volgende uit de vorige query:

  • Het namespace-trefwoord in de XQuery Prolog definieert een namespace-prefix. Dit voorvoegsel wordt later gebruikt in de query-inhoud.

  • De contextwisselingstokens, {) en (}, worden gebruikt om de query van XML-constructie naar query-evaluatie te schakelen.

  • De sql:column() wordt gebruikt om een relationele waarde op te nemen in de XML die wordt geconstrueerd.

  • Bij het construeren van het element haalt <Location> $wc/@* alle locatieattributen van het werkcentrum op.

  • De string()- functie geeft de stringwaarde van het <step> element terug.

Dit is een gedeeltelijk resultaat:

<ManuInstr ProdModelID="7" ProductModelName="HL Touring Frame">  
   <Location LocationID="10" SetupHours="0.5"   
            MachineHours="3" LaborHours="2.5" LotSize="100">  
     <step1>Insert aluminum sheet MS-2341 into the T-85A   
             framing tool.</step1>  
   </Location>  
   <Location LocationID="20" SetupHours="0.15"   
            MachineHours="2" LaborHours="1.75" LotSize="1">  
      <step1>Assemble all frame components following   
             blueprint 1299.</step1>  
   </Location>  
...  
</ManuInstr>   

B. Vind alle telefoonnummers in de kolom AdditionalContactInfo

De volgende zoekopdracht haalt extra telefoonnummers op voor een specifiek klantcontact door de hele hiërarchie te doorzoeken naar het <telephoneNumber> element. Omdat het <telephoneNumber> element overal in de hiërarchie kan voorkomen, gebruikt de query de descendant en zelfoperator (//) in de zoekopdracht.

SELECT AdditionalContactInfo.query('  
 declare namespace ci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";  
 declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";  
for $ph in /ci:AdditionalContactInfo//act:telephoneNumber  
   return  
      $ph/act:number  
') as x  
FROM  Person.Contact  
WHERE ContactID = 1  

Dit is het resultaat:

\<act:number   
  xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">  
  111-111-1111  
\</act:number>  
\<act:number   
  xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">  
  112-111-1111  
\</act:number>  

Om alleen de top-niveau telefoonnummers op te halen, specifiek de <telephoneNumber> kindelementen van <AdditionalContactInfo>, verandert de FOR-uitdrukking in de zoekopdracht naar

for $ph in /ci:AdditionalContactInfo/act:telephoneNumber.