Compartir a través de


Consultas XQuery con jerarquía

Casi todas las columnas de tipo xml de la base de datos AdventureWorks2008R2 son documentos semiestructurados. Por lo tanto, los documentos almacenados en cada fila pueden tener un aspecto diferente. Los ejemplos de consultas incluidos en este tema muestran cómo extraer información de estos documentos.

Ejemplos

A. A partir de los documentos de instrucciones de fabricación, recupere ubicaciones de los centros de trabajo junto con el primer paso del proceso de fabricación en esas ubicaciones

Para el modelo de producto 7, la consulta genera XML que incluye el elemento <ManuInstr>, con los atributos ProductModelID y ProductModelName, y uno o varios elementos secundarios <Location>.

Cada elemento <Location> tiene su propio conjunto de atributos y un elemento secundario <step>. Este elemento secundario <step> es el primer paso del proceso de fabricación en la ubicación del centro de trabajo.

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;

Observe lo siguiente en la consulta anterior:

  • La palabra clave namespace en el prólogo de las consultas XQuery define un prefijo de espacio de nombres. Este prefijo se utiliza posteriormente en el cuerpo de la consulta.

  • Los tokens de contexto, {) y (}, se utilizan para cambiar la consulta de construcción de XML a evaluación de consulta.

  • sql:column() se utiliza para incluir un valor relacional en el XML que se está generando.

  • Al construir el elemento <Location>, $wc/@* recupera todos los atributos de ubicación de centros de trabajo.

  • La función string() devuelve el valor de cadena desde el elemento <step>.

Éste es un resultado parcial:

<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. Buscar todos los números de teléfono de la columna AdditionalContactInfo

La siguiente consulta recupera números de teléfono adicionales para un contacto de cliente específico buscando el elemento <telephoneNumber> en toda la jerarquía. Dado que el elemento <telephoneNumber> puede aparecer en cualquier lugar de la jerarquía, la consulta usa el operador descendant y self (//) en la búsqueda.

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;

El resultado es el siguiente:

<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>

Para recuperar únicamente los números de teléfono de nivel superior, específicamente los elementos secundarios <telephoneNumber> de <AdditionalContactInfo>, la expresión FOR de la consulta cambia a

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