Partilhar via


Tipos de Dados XPath (SQLXML 4.0)

Aplica-se a:SQL ServerBanco de Dados SQL do Azure

O Microsoft SQL Server, XPath e XML Schema (XSD) têm tipos de dados muito diferentes. Por exemplo, o XPath não tem tipos de dados inteiros ou datados, mas o SQL Server e o XSD têm muitos. O XSD utiliza precisão de nanossegundos para valores de tempo, e o SQL Server utiliza no máximo precisão de 1/300 de segundo. Consequentemente, mapear um tipo de dado para outro nem sempre é possível. Para mais informações sobre mapear tipos de dados SQL Server para tipos de dados XSD, consulte Coerções de Tipos de Dados e a Anotação sql:datatype (SQLXML 4.0).

O XPath tem três tipos de dados: string, number e boolean. O tipo de dado numérico é sempre um IEEE 754 de dupla precisão em ponto flutuante. O tipo de dadofloat(53) do SQL Server é o número mais próximo do XPath. No entanto, float(53) não é exatamente IEEE 754. Por exemplo, nem NaN (Não-um-Número) nem o infinito são usados. Tentar converter uma cadeia não numérica em número e tentar dividir por zero resulta num erro.

Conversões XPath

Quando usa uma consulta XPath como OrderDetail[@UnitPrice > "10.0"], as conversões implícitas e explícitas de tipos de dados podem alterar o significado da consulta de formas subtis. Por isso, é importante compreender como os tipos de dados XPath são implementados. A especificação da linguagem XPath, XML Path Language (XPath) versão 1.0 Recomendação Proposta do W3C 8 de outubro de 1999, pode ser encontrada no site do W3C em http://www.w3.org/TR/1999/PR-xpath-19991008.html.

Os operadores XPath dividem-se em quatro categorias:

  • Operadores booleanos (e, ou)

  • Operadores relacionais (<, >, <=, >=)

  • Operadores de igualdade (=, !=)

  • Operadores aritméticos (+, -, *, div, mod)

Cada categoria de operador converte os seus operandos de forma diferente. Os operadores XPath convertem implicitamente os seus operandos, se necessário. Os operadores aritméticos convertem os seus operandos em número e resultam num valor numérico. Os operadores booleanos convertem os seus operandos para booleanos e resultam num valor booleano. Operadores relacionais e operadores de igualdade resultam num valor booleano. No entanto, têm regras de conversão diferentes dependendo dos tipos de dados originais dos seus operandos, como mostrado nesta tabela.

Operando Operador relacional Operador de igualdade
Ambos os operandos são conjuntos de nós. TRUE se e somente se houver um nó num conjunto e um nó no segundo conjunto tais que a comparação dos seus valores de string seja TRUE. Igual.
Um é um conjunto de nós, o outro uma cadeia. VERDADEIRO se e somente se existir um nó no conjunto de nós tal que, quando convertido em número, a comparação com a cadeia convertida em número seja VERDADEIRA. TRUE se e somente se existir um nó no conjunto de nós tal que, quando convertido em cadeia, a comparação com a cadeia seja TRUE.
Um é um conjunto de nós, o outro um número. TRUE se e somente se existir um nó no conjunto de nós tal que, ao ser convertido em número, a comparação com o número seja TRUE. Igual.
Um é um conjunto de nós, o outro um booleano. TRUE se e somente se existir um nó no conjunto de nós tal que, quando convertido para booleano e depois para número, a comparação com o booleano convertido em número seja VERDADEIRA. TRUE se, e somente se, existir um nó no conjunto de nós tal que, quando convertido para booleano, a comparação com o booleano seja TRUE.
Nenhum dos dois é um conjunto de nós. Converte ambos os operandos em número e depois compara. Converter ambos os operandos para um tipo comum e depois comparar. Converter para booleano se qualquer um for booleano, número se qualquer um for número; caso contrário, converte para string.

Observação

Como os operadores relacionais XPath convertem sempre os seus operandos em número, as comparações de cadeias não são possíveis. Para incluir comparações de datas, o SQL Server 2000 oferece esta variação à especificação XPath: Quando um operador relacional compara uma string com uma string, um conjunto de nós com uma string, ou um conjunto de nós com valores de string, é realizada uma comparação de string (não uma comparação numérica ).

Node-Set Conversões

As conversões de conjuntos de nós nem sempre são intuitivas. Um conjunto de nós é convertido numa cadeia tomando o valor da cadeia apenas do primeiro nó do conjunto. Um conjunto de nós é convertido em número convertendo-o em cadeia, e depois convertendo cadeia emnúmero. Um conjunto de nós é convertido para booleano testando a sua existência.

Observação

O SQL Server não realiza seleção posicional em conjuntos de nós: por exemplo, a consulta Customer[3] XPath significa o terceiro cliente; este tipo de seleção posicional não é suportado no SQL Server. Portanto, as conversões de conjunto de nó para-cadeia ou conjunto-de nó para número , conforme descritas pela especificação XPath, não são implementadas. O SQL Server utiliza a semântica "qualquer" sempre que a especificação XPath especifica a semântica "first". Por exemplo, com base na especificação XPath do W3C, a consulta Order[OrderDetail/@UnitPrice > 10.0] XPath seleciona as ordens com o primeiro OrderDetail que tenha um UnitPrice superior a 10.0. No SQL Server, esta consulta XPath seleciona essas ordens com qualquer OrderDetail que tenha um UnitPrice superior a 10.0.

A conversão para booleano gera um teste de existência; portanto, a consulta Products[@Discontinued=true()] XPath é equivalente à expressão SQL "Products.Discontinued is not null", e não à expressão SQL "Products.Discontinued = 1". Para tornar a consulta equivalente à expressão SQL posterior, primeiro converte o conjunto de nós para um tipo não booleano , como number. Por exemplo, Products[number(@Discontinued) = true()].

Como a maioria dos operadores é definida como VERDADEIRA se forem VERDADEIRAS para qualquer um ou um dos nós do conjunto de nós, estas operações avaliam sempre como FALSE se o conjunto de nós estiver vazio. Assim, se A é vazio, tanto A = B como são A != B FALSOS, e not(A=B) e not(A!=B) são VERDADEIROS.

Normalmente, existe um atributo ou elemento que corresponde a uma coluna se o valor dessa coluna na base de dados não for nulo. Elementos que mapeiam para linhas existem se existirem filhos deles.

Observação

Elementos anotados com is-constante existem sempre. Consequentemente, os predicados XPath não podem ser usados em elementos que são constantes .

Quando um conjunto de nós é convertido em cadeia ou número, o seu tipo XDR (se existir) é inspecionado no esquema anotado e esse tipo é usado para determinar a conversão necessária.

Mapear Tipos de Dados XDR para Tipos de Dados XPath

O tipo de dado XPath de um nó é derivado do tipo de dados XDR no esquema, como mostrado na tabela seguinte (o nó EmployeeID é usado para fins ilustrativos).

Tipo de dados XDR Equivalente

Tipo de dados XPath
Conversão SQL Server utilizada
Nonebin.base64bin.hex N/A NoneEmployeeID
Booleano Booleano CONVERT(bit, EmployeeID)
número, int, float, i1, i2, i4, i8, r4, r8ui1, ui2, ui4, ui8 número CONVERT(float(53), EmployeeID)
id, idref, idrefsentity, entities, enumerationnotation, nmtokens, nmtokens, chardate, Timedate, Time.tz, string, uri, uuid cadeia (de caracteres) CONVERT(nvarchar(4000), EmployeeID, 126)
fixed14.4 N/A (Não existe nenhum tipo de dado no XPath equivalente ao tipo de dado fixed14.4 XDR) CONVERT (dinheiro, EmployeeID)
date cadeia (de caracteres) ESQUERDA(CONVERTER(nvarchar(4000), EmployeeID, 126), 10)
time

time.tz
cadeia (de caracteres) SUBSTRING(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24)

As conversões de data e hora são concebidas para funcionar, quer o valor seja armazenado na base de dados usando o tipo de datae hora do SQL Server ou uma cadeia de caracteres. Note que o tipo de datadata-hora do SQL Server não utiliza fuso horário e tem uma precisão menor do que o tipo de data XML de tempo . Para incluir o tipo de dado do fuso horário ou precisão adicional, armazene os dados no SQL Server usando um tipo de cadeia.

Quando um nó é convertido do seu tipo de dados XDR para o tipo XPath, por vezes é necessária uma conversão adicional (de um tipo de dado XPath para outro tipo XPath). Por exemplo, considere esta consulta XPath:

(@m + 3) = 4  

Se @m for do tipo de dados fixed14.4 XDR, a conversão do tipo de dados XDR para o tipo de dados XPath é feita utilizando:

CONVERT(money, m)  

Nesta conversão, o nó m é convertido de fixed14.4 para dinheiro. No entanto, adicionar o valor de 3 requer conversão adicional:

CONVERT(float(CONVERT(money, m))  

A expressão XPath é avaliada como:

CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)  

Como mostrado na tabela seguinte, esta é a mesma conversão aplicada a outras expressões XPath (como literais ou expressões compostas).

X é desconhecido X é uma cadeia X é número X é booleano
string(X) CONVERT (nvarchar(4000), X, 126) - CONVERT (nvarchar(4000), X, 126) CASO QUANDO X ENTÃO N'verdadeiro' CASO CONTRÁRIO N'falso' FIM
número(X) CONVERT (float(53), X) CONVERT (float(53), X) - CASO QUANDO X ENTÃO 1 SE NÃO 0 FIM
Booleano(X) - LEN(X) > 0 X != 0 -

Examples

A. Converter um tipo de dado numa consulta XPath

Na consulta XPath seguinte especificada contra um esquema XSD anotado, a consulta seleciona todos os nós Employee com o valor do atributo EmployeeID E-1, onde "E-" é o prefixo especificado usando a anotação sql:id-prefix .

Employee[@EmployeeID="E-1"]

O predicado na consulta é equivalente à expressão SQL:

N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'

Como o EmployeeID é um dos valores de tipo de dados id (idref, idrefs, nmtokens, nmtokens, etc.) no esquema XSD, o EmployeeID é convertido para o tipo de dados XPath usando as regras de conversão descritas anteriormente.

CONVERT(nvarchar(4000), Employees.EmployeeID, 126)

O prefixo "E-" é adicionado à cadeia, e o resultado é então comparado com N'E-1'.

B. Realizar várias conversões de tipos de dados numa consulta XPath

Considere esta consulta XPath especificada contra um esquema XSD anotado: OrderDetail[@UnitPrice * @OrderQty > 98]

Esta consulta XPath devolve todos os <elementos OrderDetail> que satisfazem o predicado @UnitPrice * @OrderQty > 98. Se o UnitPrice for anotado com um tipo de dado fixed14.4 no esquema anotado, este predicado é equivalente à expressão SQL:

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) * CONVERT(float(53), OrderDetail.OrderQty) > CONVERT(float(53), 98)

Ao converter os valores na consulta XPath, a primeira conversão converte o tipo de dado XDR para o tipo XPath. Como o tipo de dados XSD UnitPrice é fixed14.4, conforme descrito na tabela anterior, esta é a primeira conversão utilizada:

CONVERT(money, OrderDetail.UnitPrice))   

Como os operadores aritméticos convertem os seus operandos para o tipo de dado número XPath, aplica-se a segunda conversão (de um tipo de dado XPath para outro tipo XPath), na qual o valor é convertido para float(53) (float(53) está próximo do tipo de dado número XPath):

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice))   

Assumindo que o atributo OrderQty não tem um tipo de dado XSD, o OrderQty é convertido para um tipo de dado XPath numérico numa única conversão:

CONVERT(float(53), OrderDetail.OrderQty)  

De forma semelhante, o valor 98 é convertido para o tipo de dado número XPath:

CONVERT(float(53), 98)  

Observação

Se o tipo de dado XSD usado no esquema for incompatível com o tipo de dado SQL Server subjacente na base de dados, ou se for realizada uma conversão impossível do tipo de dado XPath, o SQL Server pode devolver um erro. Por exemplo, se o atributo EmployeeID for anotado com a anotação do prefixo id , o XPath Employee[@EmployeeID=1] gera um erro, porque o EmployeeID tem a anotação do prefixo id e não pode ser convertido em número.