Compartir a través de


Casos de uso generales de XQuery

Se aplica a:SQL Server

En este tema se proporcionan ejemplos generales del uso de XQuery.

Ejemplos

A. Consultar descripciones del catálogo para encontrar productos y pesos

La siguiente consulta devuelve los Id. de modelo de producto y los pesos, si existen, de la descripción del catálogo de productos. La consulta crea XML con el formato siguiente:

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

Esta es la consulta:

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  

Observe lo siguiente en la consulta anterior:

  • La palabra clave namespace del prólogo XQuery define un prefijo de espacio de nombres que se usa en el cuerpo de la consulta.

  • El cuerpo de la consulta genera el XML requerido.

  • En la cláusula WHERE, el método exist() se usa para buscar solo las filas que contienen descripciones del catálogo de productos. Es decir, el XML que contiene el <ProductDescription> elemento .

El resultado es el siguiente:

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

La consulta siguiente recupera la misma información, pero solo para los modelos de producto cuya descripción del catálogo incluye el peso, el <Weight> elemento , en las especificaciones, el <Specifications> elemento . En este ejemplo se utiliza WITH XMLNAMESPACES para declarar el prefijo pd y su enlace de espacio de nombres. De este modo, el enlace no se describe tanto en el método query() como en el método exist().

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  

En la consulta anterior, el método exist() del tipo de datos xml en la cláusula WHERE comprueba si hay un <Weight> elemento en el <Specifications> elemento .

B. Encontrar identificadores de modelos de productos para modelos de productos en cuyas descripciones de catálogo se incluyan imágenes de pequeño tamaño y ángulo frontal

La descripción del catálogo de productos XML incluye las imágenes del producto, el <Picture> elemento . Cada imagen tiene varias propiedades. Estos incluyen el ángulo de imagen, el <Angle> elemento y el tamaño, el <Size> elemento .

Para los modelos de productos en cuyas descripciones de catálogo se incluyen imágenes de pequeño tamaño y ángulo frontal, la consulta genera XML con el siguiente formato:

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

Observe lo siguiente en la consulta anterior:

  • En la cláusula WHERE, el método exist() se usa para recuperar solo las filas que tienen descripciones del catálogo de productos con el <Picture> elemento .

  • La cláusula WHERE usa el método value() dos veces para comparar los valores de los <Size> elementos y <Angle> .

Éste es un resultado parcial:

<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. Cree una lista plana del nombre del modelo de producto y los pares de características, con cada par incluido en el <elemento Features> .

En la descripción de catálogo del modelo de producto, el XML incluye varias características del producto. Todas estas características se incluyen en el <Features> elemento . La consulta usa XML Construction (XQuery) para construir el XML necesario. La expresión incluida entre llaves se reemplaza por el resultado.

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  

Observe lo siguiente en la consulta anterior:

  • $pd/p1:Features/* devuelve solo los elementos secundarios del nodo de elemento de <Features>, pero $pd/p1:Features/node() devuelve todos los nodos. donde se incluyen los nodos de elemento, nodos de texto, instrucciones de procesamiento y comentarios.

  • Los dos bucles FOR generan un producto cartesiano a partir del que se devuelven el nombre de producto y la característica individual.

  • ProductName es un atributo. La construcción XML de esta consulta lo devuelve como un elemento.

Éste es un resultado parcial:

<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. En la descripción del catálogo de un modelo de producto, enumere el nombre del modelo de producto, el identificador de modelo y las características agrupadas dentro de un <elemento Product> .

Con la información almacenada en la descripción del catálogo del modelo de producto, en la consulta siguiente se muestra el nombre del modelo de producto, el identificador de modelo y las características agrupadas dentro de un <elemento Product> .

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  

Éste es un resultado parcial:

<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. Recuperar descripciones de características de modelos de productos

La consulta siguiente construye XML que incluye un <Product> elemento que tiene atributos ProducModelID, ProductModelName y las dos primeras características del producto. En concreto, las dos primeras características del producto son los dos primeros elementos secundarios del <Features> elemento . Si hay más características, devuelve un elemento vacío <There-is-more/> .

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  

Observe lo siguiente en la consulta anterior:

  • For ... La estructura del bucle RETURN recupera las dos primeras características del producto. La función position() se usa para buscar la posición de los elementos de la secuencia.

F. Buscar nombres de elementos que terminen en "ons" en la descripción del catálogo de productos

La consulta siguiente busca en las descripciones del catálogo y devuelve todos los elementos del <ProductDescription> elemento cuyo nombre termina con "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  

Éste es un resultado parcial:

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

G. Buscar descripciones resumidas que contengan la palabra "Aerodynamic"

La siguiente consulta recupera los modelos de productos cuyas descripciones de catálogo incluyen la palabra "Aerodynamic" en la descripción resumida:

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  

Tenga en cuenta que la consulta SELECT especifica los métodos query() y value() del tipo de datos xml . Por lo tanto, en lugar de repetir la declaración de espacios de nombres dos veces en dos prólogos de consulta distintos, se utiliza el prefijo pd en la consulta y se define una sola vez mediante WITH XMLNAMESPACES.

Observe lo siguiente en la consulta anterior:

  • La cláusula WHERE se usa para recuperar solo las filas donde la descripción del catálogo contiene la palabra "Aerodinámica" en el <Summary> elemento.

  • La función contains() se usa para ver si la palabra se incluye en el texto.

  • El método value() del tipo de datos xml compara el valor devuelto por contains() a 1.

El resultado es el siguiente:

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. Buscar modelos de productos en cuyas descripciones de catálogo no se incluyan imágenes del modelo de producto

La consulta siguiente recupera ProductModelIDs para los modelos de producto cuyas descripciones de catálogo no incluyen ningún <Picture> elemento.

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  

Observe lo siguiente en la consulta anterior:

  • Si el método exist() de la cláusula WHERE devuelve False (0), se devuelve el identificador del modelo de producto. De lo contrario, no se devuelve.

  • Dado que todas las descripciones del producto incluyen un <Picture> elemento , el conjunto de resultados está vacío en este caso.

Consulte también

Consultas XQuery con jerarquía
Consultas XQuery basadas en el orden
Funciones de XQuery para controlar datos relacionales
Buscar cadenas en XQuery
Controlar espacios de nombres en XQuery
Agregar espacios de nombres a consultas con WITH XMLNAMESPACES
Datos XML (SQL Server)
Referencia del lenguaje XQuery (SQL Server)