Compartir a través de


Casos de uso generales de XQuery

Se aplica a:SQL Server

En este artículo se proporcionan ejemplos generales de 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;

Tenga en cuenta las siguientes consideraciones de la consulta anterior:

  • La namespace palabra clave 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 WHERE cláusula , el exist() método se usa para buscar solo las filas que contienen descripciones del catálogo de productos. Es decir, el XML que contiene el <ProductDescription> elemento .

Este es el resultado:

<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 usa WITH XMLNAMESPACES para declarar el pd prefijo y su enlace de espacio de nombres. De este modo, el enlace no se describe tanto en el query() método como en el exist() método .

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 exist() método del tipo de datos xml de la WHERE cláusula 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, incluido 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'

Tenga en cuenta las siguientes consideraciones de la consulta anterior:

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

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

Este 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 la construcción XML (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;

Tenga en cuenta las siguientes consideraciones de 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 FOR bucles generan un producto cartesiano a partir del cual se devuelve el nombre del producto y la característica individual.

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

Este 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, la consulta siguiente enumera el nombre del modelo de producto, el identificador de modelo y las características agrupadas dentro de un <Product> elemento.

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;

Este 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 ProductModelIDlos atributos , 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;

Tenga en cuenta las siguientes consideraciones de la consulta anterior:

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

F. Buscar nombres de elementos de la descripción del catálogo de productos que terminan con ons

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;

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

La SELECT consulta 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 de diferencia, el prefijo pd se usa en la consulta y se define solo una vez mediante WITH XMLNAMESPACES.

Tenga en cuenta las siguientes consideraciones de la consulta anterior:

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

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

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

Este es el resultado:

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 producto cuyas descripciones de catálogo no 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;

Tenga en cuenta las siguientes consideraciones de la consulta anterior:

  • Si el exist() método de la WHERE cláusula 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.