Expresiones SequenceType (XQuery)

Se aplica a:SQL Server

En XQuery, un valor siempre es una secuencia. Se hace referencia a los tipos de valor como tipos de secuencia. El tipo de secuencia se puede usar en una instancia de expresión XQuery. La sintaxis SequenceType descrita en la especificación de XQuery se utiliza cuando se debe hacer referencia a un tipo de una expresión XQuery.

El nombre del tipo atómico también se puede usar en la conversión como expresión XQuery. En SQL Server, la instancia de y la conversión como expresiones XQuery en SequenceTypes se admiten parcialmente.

Operador instance of

La instancia del operador se puede usar para determinar el tipo dinámico, o en tiempo de ejecución, del valor de la expresión especificada. Por ejemplo:

  
Expression instance of SequenceType[Occurrence indicator]  

Tenga en cuenta que el instance of operador , Occurrence indicatorespecifica la cardinalidad, el número de elementos de la secuencia resultante. Si no se especifica esto, se supone que la cardinalidad es 1. En SQL Server, solo se admite el indicador de repetición de signo de interrogación (?). El indicador de repetición ? indica que Expression puede devolver cero o un elemento. Si se especifica el indicador de repetición ? , instance of devuelve True cuando el Expression tipo coincide con el especificado SequenceType, independientemente de si Expression devuelve un singleton o una secuencia vacía.

Si no se especifica el indicador de repetición ? , sequence of devuelve True solo cuando el Expression tipo coincide con el Type especificado y Expression devuelve un singleton.

Nota Los indicadores de repetición de signo más (+) y asterisco (*) no se admiten en SQL Server.

En los ejemplos siguientes se muestra el uso de lainstancia del operador XQuery.

Ejemplo A

En el ejemplo siguiente se crea una variable de tipo xml y se especifica una consulta en ella. La expresión de consulta especifica un operador instance of para determinar si el tipo dinámico del valor devuelto por el primer operando coincide con el tipo especificado en el segundo operando.

La consulta siguiente devuelve True, porque el valor 125 es una instancia del tipo especificado, xs:integer:

declare @x xml  
set @x=''  
select @x.query('125 instance of xs:integer')  
go  

La consulta siguiente devuelve True, pues el valor devuelto por la expresión, /a[1], del primer operando es un elemento:

declare @x xml  
set @x='<a>1</a>'  
select @x.query('/a[1] instance of element()')  
go  

De forma similar, instance of devuelve True en la consulta siguiente, porque el tipo de valor de la primera expresión es un atributo:

declare @x xml  
set @x='<a attr1="x">1</a>'  
select @x.query('/a[1]/@attr1 instance of attribute()')  
go  

En el ejemplo siguiente, la expresión, data(/a[1], devuelve un valor atómico con el tipo xdt:untypedAtomic. Por lo tanto, instance of devuelve True.

declare @x xml  
set @x='<a>1</a>'  
select @x.query('data(/a[1]) instance of xdt:untypedAtomic')  
go  

En la consulta siguiente, la expresión, data(/a[1]/@attrA, devuelve un valor atómico sin tipo. Por lo tanto, instance of devuelve True.

declare @x xml  
set @x='<a attrA="X">1</a>'  
select @x.query('data(/a[1]/@attrA) instance of xdt:untypedAtomic')  
go  

Ejemplo B

En este ejemplo, se consulta una columna con el tipo XML de la base de datos de ejemplo AdventureWorks. La colección de esquemas XML asociada con la columna que se consulta proporciona la información de escritura.

En la expresión, data() devuelve el valor con tipo del atributo ProductModelID cuyo tipo es xs:string según el esquema asociado a la columna. Por lo tanto, instance of devuelve True.

SELECT CatalogDescription.query('  
   declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
   data(/PD:ProductDescription[1]/@ProductModelID) instance of xs:string  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID = 19  

Para obtener más información, vea Comparar XML con tipo y XML sin tipo.

Las consultas siguientes usan la expresiónboolean instance of para determinar si el atributo LocationID es de tipo xs:integer:

SELECT Instructions.query('  
   declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
   /AWMI:root[1]/AWMI:Location[1]/@LocationID instance of attribute(LocationID,xs:integer)  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID=7  

La consulta siguiente se especifica con la columna XML de tipo CatalogDescription. La colección de esquemas XML asociada con esta columna proporciona la información de escritura.

La consulta usa la prueba element(ElementName, ElementType?) en la expresión instance of para comprobar que /PD:ProductDescription[1] devuelve un nodo de elemento con un nombre y un tipo específicos.

SELECT CatalogDescription.query('  
     declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
     /PD:ProductDescription[1] instance of element(PD:ProductDescription, PD:ProductDescription?)  
    ') as Result  
FROM  Production.ProductModel  
where ProductModelID=19  

La consulta devuelve True.

Ejemplo C

Al usar tipos de unión, la instance of expresión de SQL Server tiene una limitación: en concreto, cuando el tipo de un elemento o atributo es un tipo de unión, instance of es posible que no determine el tipo exacto. Por tanto, una consulta devolverá False, a menos que los tipos atómicos utilizados en SequenceType sean los elementos principales máximos del tipo real de la expresión de la jerarquía simpleType. Es decir, los tipos atómicos especificados en SequenceType deben ser secundarios directos de anySimpleType. Para obtener información sobre la jerarquía de tipos, vea Reglas de conversión de tipos en XQuery.

En la siguiente consulta de ejemplo se realiza lo siguiente:

  • Se crea una colección de esquemas XML con un tipo de unión, como un tipo entero o de cadena, definido en la misma.

  • Declare una variable xml con tipo mediante la colección de esquemas XML.

  • Se asigna una instancia XML de ejemplo a la variable.

  • Se consulta la variable para ilustrar el comportamiento de instance of cuando se trata con un tipo de unión.

Esta es la consulta:

CREATE XML SCHEMA COLLECTION MyTestSchema AS '  
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ns" xmlns:ns="http://ns">  
<simpleType name="MyUnionType">  
<union memberTypes="integer string"/>  
</simpleType>  
<element name="TestElement" type="ns:MyUnionType"/>  
</schema>'  
Go  

La consulta siguiente devuelve False, pues el valor de SequenceType especificado en la expresión instance of no es el principal máximo del tipo real de la expresión especificada. Es decir, el valor de <TestElement> es un tipo entero. El principal máximo es xs:decimal. No obstante, no se especifica como el segundo operando del operador instance of.

SET QUOTED_IDENTIFIER ON  
DECLARE @var XML(MyTestSchema)  
  
SET @var = '<TestElement xmlns="http://ns">123</TestElement>'  
  
SELECT @var.query('declare namespace ns="http://ns"   
   data(/ns:TestElement[1]) instance of xs:integer')  
go  

Puesto que el principal máximo de xs:integer es xs:decimal, la consulta devolverá True si se modifica la consulta y se especifica xs:decimal como SequenceType en la misma.

SET QUOTED_IDENTIFIER ON  
DECLARE @var XML(MyTestSchema)  
SET @var = '<TestElement xmlns="http://ns">123</TestElement>'  
SELECT @var.query('declare namespace ns="http://ns"     
   data(/ns:TestElement[1]) instance of xs:decimal')  
go  

Ejemplo D

En este ejemplo, primero se crea una colección de esquemas XML y se usa para escribir una variable xml . A continuación, se consulta la variable xml con tipo para ilustrar la instance of funcionalidad.

La siguiente colección de esquemas XML define un tipo simple, myType y un elemento, <root>, de tipo myType:

drop xml schema collection SC  
go  
CREATE XML SCHEMA COLLECTION SC AS '  
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="myNS" xmlns:ns="myNS"  
xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes">  
      <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/>  
      <simpleType name="myType">  
           <restriction base="s:varchar">  
                  <maxLength value="20"/>  
            </restriction>  
      </simpleType>  
      <element name="root" type="ns:myType"/>  
</schema>'  
Go  

Ahora cree una variable xml con tipo y consulte:

DECLARE @var XML(SC)  
SET @var = '<root xmlns="myNS">My data</root>'  
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";  
declare namespace ns="myNS";   
   data(/ns:root[1]) instance of ns:myType')  
go  

Puesto que el tipo myType procede por restricción de un tipo varchar definido en el esquema sqltypes, instance of también devolverá True.

DECLARE @var XML(SC)  
SET @var = '<root xmlns="myNS">My data</root>'  
SELECT @var.query('declare namespace sqltypes = "https://schemas.microsoft.com/sqlserver/2004/sqltypes";  
declare namespace ns="myNS";   
data(/ns:root[1]) instance of sqltypes:varchar?')  
go  

Ejemplo E

En el ejemplo siguiente, la expresión recupera uno de los valores del atributo IDREFS y utiliza instance of para determinar si el valor es del tipo IDREF. En el ejemplo, se realizan las tareas siguientes:

  • Crea una colección de esquemas XML en la que el <Customer> elemento tiene un atributo de tipo IdREFS OrderList y el <Order> elemento tiene un atributo de tipo Id. de OrderID .

  • Crea una variable xml con tipo y le asigna una instancia XML de ejemplo.

  • Se especifica una consulta con la variable. La expresión de consulta recupera el primer valor de identificador de pedido del atributo de tipo IdRERS OrderList del primer <Customer>. El valor recuperado es de tipo IDREF. Por lo tanto, instance of devuelve True.

create xml schema collection SC as  
'<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:Customers="Customers" targetNamespace="Customers">  
            <element name="Customers" type="Customers:CustomersType"/>  
            <complexType name="CustomersType">  
                        <sequence>  
                            <element name="Customer" type="Customers:CustomerType" minOccurs="0" maxOccurs="unbounded" />  
                        </sequence>  
            </complexType>  
             <complexType name="OrderType">  
                <sequence minOccurs="0" maxOccurs="unbounded">  
                            <choice>  
                                <element name="OrderValue" type="integer" minOccurs="0" maxOccurs="unbounded"/>  
                            </choice>  
                </sequence>                                             
                <attribute name="OrderID" type="ID" />  
            </complexType>  
  
            <complexType name="CustomerType">  
                <sequence minOccurs="0" maxOccurs="unbounded">  
                            <choice>  
                                <element name="spouse" type="string" minOccurs="0" maxOccurs="unbounded"/>  
                                <element name="Order" type="Customers:OrderType" minOccurs="0" maxOccurs="unbounded"/>  
                            </choice>  
                </sequence>                                             
                <attribute name="CustomerID" type="string" />  
                <attribute name="OrderList" type="IDREFS" />  
            </complexType>  
 </schema>'  
go  
declare @x xml(SC)  
set @x='<CustOrders:Customers xmlns:CustOrders="Customers">  
                <Customer CustomerID="C1" OrderList="OrderA OrderB"  >  
                              <spouse>Jenny</spouse>  
                                <Order OrderID="OrderA"><OrderValue>11</OrderValue></Order>  
                                <Order OrderID="OrderB"><OrderValue>22</OrderValue></Order>  
  
                </Customer>  
                <Customer CustomerID="C2" OrderList="OrderC OrderD" >  
                                <spouse>John</spouse>  
                                <Order OrderID="OrderC"><OrderValue>33</OrderValue></Order>  
                                <Order OrderID="OrderD"><OrderValue>44</OrderValue></Order>  
  
                        </Customer>  
                <Customer CustomerID="C3"  OrderList="OrderE OrderF" >  
                                <spouse>Jane</spouse>  
                                <Order OrderID="OrderE"><OrderValue>55</OrderValue></Order>  
                                <Order OrderID="OrderF"><OrderValue>55</OrderValue></Order>  
                </Customer>  
                <Customer CustomerID="C4"  OrderList="OrderG"  >  
                                <spouse>Tim</spouse>  
                                <Order OrderID="OrderG"><OrderValue>66</OrderValue></Order>  
                        </Customer>  
                <Customer CustomerID="C5"  >  
                </Customer>  
                <Customer CustomerID="C6" >  
                </Customer>  
                <Customer CustomerID="C7"  >  
                </Customer>  
</CustOrders:Customers>'  
  
select @x.query(' declare namespace CustOrders="Customers";   
 data(CustOrders:Customers/Customer[1]/@OrderList)[1] instance of xs:IDREF ? ') as XML_result  

Limitaciones de la implementación

Éstas son las limitaciones:

  • Los tipos de secuencia schema-element() y schema-attribute() no se admiten para la comparación con el instance of operador .

  • No se admiten las secuencias completas, como (1,2) instance of xs:integer*.

  • Cuando se usa una forma del tipo de secuencia element() que especifica un nombre de tipo, como element(ElementName, TypeName), el tipo debe calificarse con un signo de interrogación (?). Por ejemplo, element(Title, xs:string?) indica que el elemento puede ser NULL. SQL Server no admite la detección en tiempo de ejecución de la propiedad xsi:nil mediante instance of.

  • Si el valor Expression de procede de un elemento o atributo escrito como una unión, SQL Server solo puede identificar el tipo primitivo, no derivado, del que se deriva el tipo del valor. Por ejemplo, si <e1> se define para tener un tipo estático de (xs:integer | xs:string), lo siguiente devolverá False.

    data(<e1>123</e1>) instance of xs:integer  
    

    Sin embargo, data(<e1>123</e1>) instance of xs:decimal devolverá True.

  • Para los tipos de secuencia processing-instruction() y document-node(), solo se permiten formularios sin argumentos. Por ejemplo, se admite processing-instruction() pero no processing-instruction('abc').

Operador cast as

La conversión como expresión se puede usar para convertir un valor en un tipo de datos específico. Por ejemplo:

  
Expression cast as  AtomicType?  

En SQL Server, el signo de interrogación (?) es necesario después de AtomicType. Por ejemplo, como se muestra en la consulta siguiente, "2" cast as xs:integer? convierte el valor de cadena en un entero:

declare @x xml  
set @x=''  
select @x.query('"2" cast as xs:integer?')  

En la consulta siguiente, data() devuelve el valor con tipo del atributo ProductModelID, un tipo de cadena. El cast asoperador convierte el valor en xs:integer.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS PD)  
SELECT CatalogDescription.query('  
   data(/PD:ProductDescription[1]/@ProductModelID) cast as xs:integer?  
') as Result  
FROM Production.ProductModel  
WHERE ProductModelID = 19  

El uso explícito de data() no es necesario en esta consulta. La expresión cast as realiza una atomización implícita en la expresión de entrada.

Funciones de constructor

Se pueden utilizar las funciones de constructor de tipo atómico. Por ejemplo, en lugar de usar el cast as operador , "2" cast as xs:integer?puede usar la función constructor xs:integer(), como en el ejemplo siguiente:

declare @x xml  
set @x=''  
select @x.query('xs:integer("2")')  

En el ejemplo siguiente se devuelve un valor xs:date equivalente a 2000-01-01Z.

declare @x xml  
set @x=''  
select @x.query('xs:date("2000-01-01Z")')  

También se pueden utilizar constructores para los tipos atómicos definidos por el usuario. Por ejemplo, si la colección de esquemas XML asociada al tipo de datos XML define un tipo simple, se puede usar un constructor myType() para devolver un valor de ese tipo.

Limitaciones de la implementación

  • No se admiten los tipos de expresiones XQuerywitch, castable y treat .

  • convertir como requiere un signo de interrogación (?) después del tipo atómico.

  • xs:QName no se admite como un tipo para la conversión. Use expanded-QName en su lugar.

  • xs:date, xs:time y xs:datetime requieren una zona horaria, que se indica mediante una Z.

    La consulta siguiente provocará un error, pues no se ha especificado ninguna zona horaria.

    DECLARE @var XML  
    SET @var = ''  
    SELECT @var.query(' <a>{xs:date("2002-05-25")}</a>')  
    go  
    

    Si se agrega el indicador de zona horaria Z al valor, la consulta funcionará.

    DECLARE @var XML  
    SET @var = ''  
    SELECT @var.query(' <a>{xs:date("2002-05-25Z")}</a>')  
    go  
    

    El resultado es el siguiente:

    <a>2002-05-25Z</a>  
    

Consulte también

Expresiones XQuery
Sistema de tipos (XQuery)