Esecuzione di query XQuery che coinvolgono gerarchie

La maggior parte delle colonne di tipo xml nel database AdventureWorks2008R2 contiene documenti semistrutturati. I documenti archiviati nelle diverse righe possono pertanto avere aspetti diversi. Le query di esempio contenute in questo argomento illustrano come estrarre informazioni dai vari documenti.

Esempi

A. Recupero delle posizioni dei centri di lavorazione, insieme al primo passaggio di produzione eseguito in tali centri, dai documenti contenenti le istruzioni per la produzione

Per il modello di prodotto 7, la query costruisce informazioni XML che includono l'elemento <ManuInstr>, con gli attributi ProductModelID e ProductModelName e uno o più elementi figlio <Location>.

Ogni elemento <Location> ha un proprio set di attributi e un elemento figlio <step>. L'elemento figlio <step> corrisponde al primo passaggio di produzione eseguito nel centro di lavorazione.

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;

Dalla query precedente si noti quanto segue:

  • La parola chiave namespace nel prologo XQuery definisce un prefisso di spazio dei nomi. Tale prefisso verrà utilizzato in seguito nel corpo della query.

  • I token per il cambio di contesto, {) e (}, vengono utilizzati nella query per passare dalla costruzione delle informazioni XML alla valutazione della query.

  • La funzione sql:column() viene utilizzata per includere un valore relazionale nelle informazioni XML costruite.

  • Nella creazione dell'elemento <Location> $wc/@* recupera tutti gli attributi dei centri di lavorazione.

  • La funzione string() restituisce il valore stringa dall'elemento <step>.

Risultato parziale:

<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. Ricerca di tutti i numeri di telefono nella colonna AdditionalContactInfo

La query seguente recupera i numeri di telefono aggiuntivi per un determinato contatto presso un cliente cercando l'elemento <telephoneNumber> nell'intera gerarchia. Poiché l'elemento <telephoneNumber> può presentarsi ovunque nella gerarchia, la query utilizza l'operatore descendant and self (//).

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.Person
WHERE BusinessEntityID = 291;

Risultato:

<act:number 
  xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
  425-555-1112
</act:number>
<act:number 
  xmlns:act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">
  425-555-1111
</act:number>

Per recuperare solo i numeri di telefono di livello principale, in particolare gli elementi figlio <telephoneNumber> di <AdditionalContactInfo>, l'espressione FOR utilizzata nella query viene modificata come segue:

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