Partilhar via


Expressões SequenceType (XQuery)

Aplica-se a:SQL Server

No XQuery, um valor é sempre uma sequência. O tipo do valor é referido como um tipo de sequência. O tipo de sequência pode ser usado em uma instância da expressão XQuery. A sintaxe SequenceType descrita na especificação XQuery é usada quando você precisar consultar um tipo em uma expressão XQuery.

O nome do tipo atômico também pode ser usado na conversão como expressão XQuery. Em SQL Server, há suporte parcial para a instância de e conversão como expressões XQuery em SequenceTypes.

Operador instance of

A instância do operador pode ser usada para determinar o tipo dinâmico ou em tempo de execução do valor da expressão especificada. Por exemplo:

  
Expression instance of SequenceType[Occurrence indicator]  

Observe que o instance of operador , o Occurrence indicator, especifica a cardinalidade, o número de itens na sequência resultante. Se não estiver especificada, supõe-se que a cardinalidade seja 1. Em SQL Server, há suporte apenas para o indicador de ocorrência de ponto de interrogação (?). O indicador de ocorrência ? indica que Expression pode retornar zero ou um item. Se o indicador de ocorrência ? for especificado, instance of retornará True quando o Expression tipo corresponder ao especificado SequenceType, independentemente de retornar Expression um singleton ou uma sequência vazia.

Se o indicador de ocorrência ? não for especificado, sequence of retornará True somente quando o Expression tipo corresponder ao Type especificado e Expression retornará um singleton.

Nota Não há suporte para os indicadores de ocorrência de símbolo de adição (+) e asterisco (*) em SQL Server.

Os exemplos a seguir ilustram o uso dainstância do operador XQuery.

Exemplo A

O exemplo a seguir cria uma variável de tipo xml e especifica uma consulta nele. A expressão de consulta especifica um operador instance of para determinar se o tipo dinâmico do valor retornado pelo primeiro operando corresponde ao tipo especificado no segundo operando.

A consulta a seguir retorna True, porque o valor de 125 é uma instância do tipo especificado, xs:integer:

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

A consulta a seguir retorna True, pois o valor retornado pela expressão, /a [1], no primeiro operando é um elemento:

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

Da mesma forma, instance of retorna True na consulta a seguir, pois o tipo de valor da expressão na primeira expressão é um atributo:

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

No exemplo a seguir, a expressão, data(/a[1], retorna um valor atômico que é digitado como xdt:untypedAtomic. Portanto, o instance of retorna True.

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

Na consulta a seguir, a expressão, data(/a[1]/@attrA, retorna um valor atômico não digitado. Portanto, o instance of retorna True.

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

Exemplo B

Neste exemplo, você está consultando uma coluna XML digitada no banco de dados de exemplo da AdventureWorks. A coleção de esquemas XML associada com a coluna que está sendo consultada fornece as informações digitadas.

Na expressão , data() retorna o valor tipado do atributo ProductModelID cujo tipo é xs:string de acordo com o esquema associado à coluna. Portanto, o instance of retorna 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 obter mais informações, consulte Comparar XML digitado com XML não digitado.

As consultas a seguir usam a expressãoBoolean instance of para determinar se o atributo LocationID é do 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  

A consulta a seguir é especificada em relação à coluna XML CatalogDescription digitada. A coleção de esquemas XML associada com essa coluna fornece as informações digitadas.

A consulta usa o teste element(ElementName, ElementType?) na expressão instance of para verificar se o /PD:ProductDescription[1] retorna um nó de elemento de um nome e 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  

A consulta retorna True.

Exemplo C

Ao usar tipos de união, a instance of expressão em SQL Server tem uma limitação: especificamente, quando o tipo de um elemento ou atributo é um tipo de união, instance of pode não determinar o tipo exato. Por conseguinte, uma consulta retornará False, a menos que os tipos atômicos usados em SequenceType sejam o pai mais elevado do tipo real da expressão na hierarquia simpleType. Ou seja, os tipos atômicos especificados em SequenceType devem ser um filho direto de anySimpleType. Para obter informações sobre a hierarquia de tipos, consulte Regras de conversão de tipos no XQuery.

O próximo exemplo de consulta executa o seguinte:

  • Crie uma coleção de esquemas XML com um tipo de união, como um inteiro ou tipo de cadeia de caracteres, definido nele.

  • Declare uma variável xml tipada usando a coleção de esquemas XML.

  • Atribua uma instância XML de amostra à variável.

  • Consulte a variável para ilustrar o comportamento instance of ao lidar com um tipo de união.

Esta é a 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  

A consulta a seguir retorna False, pois o SequenceType especificado na expressão instance of não é o pai mais alto do tipo real da expressão especificada. Ou seja, o valor de <TestElement> é um tipo inteiro. O pai mais alto é xs:decimal. Porém, não é especificado como o segundo operando ao 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  

Como o pai mais alto de xs:integer é xs:decimal, a consulta retornará True se você modificar a consulta e especificar xs:decimal como SequenceType na consulta.

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  

Exemplo D

Neste exemplo, primeiro você cria uma coleção de esquemas XML e a usa para digitar uma variável xml . Em seguida, a variável xml tipada é consultada para ilustrar a instance of funcionalidade.

A seguinte coleção de esquemas XML define um tipo simples, myType e um elemento, <root>, do 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  

Agora, crie uma variável xml tipada e consulte-a:

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  

Como o tipo myType é derivado pela restrição de um tipo varchar definido no esquema sqltypes, instance of também retornará 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  

Exemplo E

No exemplo a seguir, a expressão recupera um dos valores do atributo IDREFS e usa instance of para determinar se o valor é do tipo IDREF. O exemplo executa o seguinte:

  • Cria uma coleção de esquemas XML na qual o <>Customerelemento tem um atributo de tipo IDREFS OrderList e o <Order> elemento tem um atributo de tipo ID OrderID.

  • Cria uma variável xml tipada e atribui uma instância XML de exemplo a ela.

  • Especifica uma consulta em relação à variável. A expressão de consulta recupera o valor da ID da primeira ordem do atributo de tipo IDRERS OrderList do primeiro <Customer>. O valor recuperado é do tipo IDREF. Portanto, instance of retorna 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  

Limitações de implementação

Estas são as limitações:

  • Não há suporte para os tipos de sequência schema-element() e schema-attribute() para comparação com o instance of operador .

  • Sequências completas, por exemplo, (1,2) instance of xs:integer*, não têm suporte.

  • Quando você está usando uma forma do tipo de sequência element() que especifica um nome de tipo, como element(ElementName, TypeName), o tipo deve ser qualificado com um ponto de interrogação (?). Por exemplo, element(Title, xs:string?) indica que o elemento pode ser nulo. SQL Server não dá suporte à detecção em tempo de execução da propriedade xsi:nil usando instance of.

  • Se o valor em Expression vier de um elemento ou atributo digitado como uma união, SQL Server só poderá identificar o tipo primitivo, não derivado, do qual o tipo do valor foi derivado. Por exemplo, se <e1> for definido para ter um tipo estático de (xs:integer | xs:string), o seguinte retornará False.

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

    Porém, data(<e1>123</e1>) instance of xs:decimal retornará True.

  • Para os tipos de sequência processing-instruction() e document-node(), somente formulários sem argumentos são permitidos. Por exemplo, processing-instruction() é permitido, mas processing-instruction('abc') não é permitido.

Operador cast as

A conversão como expressão pode ser usada para converter um valor em um tipo de dados específico. Por exemplo:

  
Expression cast as  AtomicType?  

Em SQL Server, o ponto de interrogação (?) é necessário após o AtomicType. Por exemplo, conforme mostrado na consulta a seguir, "2" cast as xs:integer? converte o valor da cadeia de caracteres em um inteiro:

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

Na consulta a seguir, data() retorna o valor tipado do atributo ProductModelID, um tipo de cadeia de caracteres. O cast asoperador converte o valor em 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  

O uso explícito de data() não é necessário nesta consulta. A expressão cast as executa atomização implícita na expressão de entrada.

Funções de construtor

Você pode usar as funções de construtor de tipo atômico. Por exemplo, em vez de usar o cast as operador , "2" cast as xs:integer?você pode usar a função de construtor xs:integer(), como no exemplo a seguir:

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

O exemplo a seguir retorna um valor xs:date igual a 2000-01-01Z.

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

Você também pode usar construtores para os tipos atômicos definidos pelo usuário. Por exemplo, se a coleção de esquemaSML associada ao tipo de dados XML definir um tipo simples, um construtor myType() poderá ser usado para retornar um valor desse tipo.

Limitações de implementação

  • As expressões XQuery typeswitch, castable e treat não têm suporte.

  • cast as requires a question mark (?) após o tipo atômico.

  • Xs:QName não tem suporte como um tipo para conversão. Em vez disso, use expanded-QName .

  • xs:date, xs:time e xs:datetime exigem um fuso horário, que é indicado por um Z.

    A consulta a seguir falha, pois o fuso horário não é especificado.

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

    Ao adicionar o indicador de fuso horário Z ao valor, a consulta funcionará.

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

    Este é o resultado:

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

Consulte Também

Expressões XQuery
Sistema de Tipos (XQuery)