Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplica-se a:SQL Server
Banco 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.