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 <>
Customer
elemento 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 usandoinstance 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, masprocessing-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 as
operador 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>