Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
platí pro:SQL Server
azure SQL Database
Microsoft SQL Server, XPath a XML Schema (XSD) mají velmi odlišné datové typy. Například XPath nemá celočíselné ani datové typy, ale SQL Server a XSD jich mají mnoho. XSD používá přesnost v nanosekundách pro časové hodnoty a SQL Server používá přesnost maximálně 1/300 sekundy. Proto není vždy možné mapovat jeden datový typ na jiný. Pro více informací o mapování datových typů SQL Server na XSD datové typy viz Data Type Coercions a sql:datatype Annotation (SQLXML 4.0).
XPath má tři datové typy: řetězec, číslo a booleovský systém. Číselný datový typ je vždy IEEE 754 s dvojitou přesností s plovoucí desetinnou čárkou. SQL Server float(53) datový typ je nejblíže číslu XPath. Nicméně float(53) není přesně IEEE 754. Například se nepoužívá ani NaN (Not-a-Number), ani nekonečno. Pokus o převod nečíselného řetězce na číslo a dělení nulou vede k chybě.
Konverze XPath
Když použijete dotaz XPath, jako OrderDetail[@UnitPrice > "10.0"]je , mohou převody implicitních a explicitních datových typů jemně změnit význam dotazu. Proto je důležité pochopit, jak jsou datové typy XPath implementovány. Specifikace jazyka XPath, XML Path Language (XPath) verze 1.0 W3C Navrhované doporučení 8. října 1999, je k nalezení na webových stránkách W3C na .http://www.w3.org/TR/1999/PR-xpath-19991008.html
Operátory XPath se dělí do čtyř kategorií:
Booleovské operátory (a, nebo)
Relační operátory (<, >, <=, >=)
Operátory rovnosti (=, !=)
Aritmetické operátory (+, -, *, div, mod)
Každá kategorie operátorů převádí své operandy jinak. XPath operátory implicitně převádějí jejich operandy, pokud je to nutné. Aritmetické operátory převádějí své operandy na čísla a vedou k číselné hodnotě. Booleovské operátory převádějí své operandy na booleovské a vedou k Booleovské hodnotě. Relační operátory a operátory rovnosti vedou k Booleově hodnotě. Mají však různá pravidla převodu v závislosti na původních datových typech svých operandů, jak je znázorněno v této tabulce.
| Operand | Relační operátor | Operátor rovnosti |
|---|---|---|
| Oba operandy jsou množiny uzlů. | PRAVDA právě tehdy, když existuje uzel v jedné množině a uzel ve druhé množině tak, že porovnání jejich řetězcových hodnot je PRAVDA. | Stejný. |
| Jeden je uzlová množina, druhý řetězec. | PRAVDA právě tehdy, když v množině uzlů existuje uzel takový, že při převodu na číslo je jeho porovnání s řetězcem převedeným na číslo PRAVDA. | PRAVDA právě tehdy, když v množině uzlů existuje uzel takový, že při převodu na řetězec je jeho porovnání s řetězcem PRAVDA. |
| Jeden je množina uzlů, druhý číslo. | PRAVDA právě tehdy, když v množině uzlů existuje uzel takový, že při převodu na číslo je jeho porovnání s číslem PRAVDA. | Stejný. |
| Jeden je množina uzlů, druhý booleovský. | PRAVDA právě tehdy, když v množině uzlů existuje uzel takový, že při převodu na boolean a poté na číslo je jeho porovnání s booleánem převedeným na číslo PRAVDA. | PRAVDA právě tehdy, když v množině uzlů existuje uzel takový, že při převodu na booleovskou hodnotu je jeho porovnání s booleovským systémem PRAVDA. |
| Ani jedna není uzlovou sadou. | Převeďte oba operandy na číslo a pak porovnávejte. | Převeďte oba operandy na společný typ a poté porovnávejte. Převeďte na booleovské , pokud je některý booleovský, na číslo , pokud je některý z nich číslo; jinak převedeme na string. |
Poznámka:
Protože relační operátory XPath vždy převádějí své operandy na čísla, není možné provádět porovnání řetězců . Pro zahrnutí datových porovnání nabízí SQL Server 2000 tuto variantu specifikace XPath: Když relační operátor porovnává řetězec se řetězcem, sadu uzlů se řetězcem nebo sadu uzlů s hodnotami řetězce se sadou uzlů s hodnotami řetězce, provádí se porovnání řetězců (nikoli porovnání čísel ).
Node-Set Přestavby
Převody uzlových množin nejsou vždy intuitivní. Množina uzlů se převede na řetězec tak, že se vezme hodnota řetězce pouze prvního uzlu v množině. Množina uzlů se převede na číslo tak, že se převede na řetězec a poté se řetězec převede na číslo. Množina uzlů je převedena na booleovskou hodnotu testováním její existence.
Poznámka:
SQL Server neprovádí výběr pozic na uzlových sadách: například dotaz Customer[3] XPath znamená třetího zákazníka; tento typ výběru pozic není v SQL Serveru podporován. Proto převody z uzlů na řetězec nebo z uzlů na číslo , jak je popsány specifikací XPath, nejsou implementovány. SQL Server používá "jakoukoli" sémantiku tam, kde specifikace XPath specifikuje "první" sémantiku. Například na základě specifikace W3C XPath dotaz Order[OrderDetail/@UnitPrice > 10.0] XPath vybírá ty objednávky s prvním OrderDetailem , které mají UnitPrice větší než 10,0. V SQL Serveru tento dotaz XPath vybírá objednávky s libovolným OrderDetailem , který má UnitPrice větší než 10.0.
Převod do booleovské funkce generuje test existence; proto je dotaz Products[@Discontinued=true()] XPath ekvivalentní SQL výrazu "Products.Discontinued is not null", nikoli SQL výrazu "Products.Discontinued = 1". Aby byl dotaz ekvivalentní tomuto SQL výrazu, nejprve převedeme sadu uzlů na nebooleovský typ, například číslo. Například: Products[number(@Discontinued) = true()].
Protože většina operátorů je definována jako PRAVDA, pokud jsou PRAVDIVÉ pro některý nebo jeden z uzlů v sadě uzlů, tyto operace vždy vyhodnotí na NEPRAVDIVÉ, pokud je množina uzlů prázdná. Pokud je tedy A prázdné, oba A = B jsou A != B NEPRAVDIVÉ a not(A=B) a a not(A!=B) PRAVDIVÉ.
Obvykle existuje atribut nebo prvek, který se mapuje na sloupec, pokud hodnota tohoto sloupce v databázi není nulová. Prvky, které se mapují na řádky, existují, pokud existují jejich potomci.
Poznámka:
Prvky anotované je konstantní vždy existují. V důsledku toho nelze XPath predikáty použít na prvky s konstantou is .
Když je množina uzlů převedena na řetězec nebo číslo, její typ XDR (pokud existuje) je zkontrolován v anotovaném schématu a tento typ se používá k určení požadované konverze.
Mapování XDR datových typů na XPath datové typy
Datový typ XPath uzlu je odvozen z datového typu XDR ve schématu, jak je uvedeno v následující tabulce (pro ilustraci je použito EmployeeID uzlu).
| Datový typ XDR | Ekvivalentní Datový typ XPath |
Použitá konverze na SQL Server |
|---|---|---|
| Nonebin.base64bin.hex | N/A | NoneEmployeeID |
| Boolean | Boolean | CONVERT(bit, EmployeeID) |
| číslo, int, float,i1, i2, i4, i8,r4, r8ui1, ui2, ui4, ui8 | číslo | CONVERT(float(53), EmployeeID) |
| id, idref, idrefsentity, entities, enumerationnotation, nmtoken, nmtokens, chardate, Timedate, Time.tz, string, uri, uuid | řetězec | KONVERT(nvarchar(4000), EmployeeID, 126) |
| fixed14.4 | N/A (V XPath neexistuje žádný datový typ, který by byl ekvivalentní datovému typu fixed14.4 XDR) | KONVERTOVAT(peníze, EmployeeID) |
| date | řetězec | LEFT (KONVERTITA(nvarchar(4000), EmployeeID, 126), 10) |
| time time.tz |
řetězec | SUBSTRING(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24) |
Převody dat a času jsou navrženy tak, aby fungovaly bez ohledu na to, zda je hodnota uložena v databázi pomocí datového typuSQL Server nebořetězce. Všimněte si, že datový typdatového času SQL Server nepoužívá časové pásmo a má menší přesnost než datový typ XML času . Pro zahrnutí datového typu časového pásma nebo další přesnosti uložte data do SQL Serveru pomocí typu řetězce .
Když je uzel převeden ze svého XDR datového typu na XPath, je někdy nutná další konverze (z jednoho datového typu XPath na jiný typ XPath). Například zvažte tento dotaz XPath:
(@m + 3) = 4
Pokud @m je datový typ fixed14.4 XDR, převod z XDR datového typu na XPath je proveden pomocí následujícího:
CONVERT(money, m)
Při této konverzi je uzel m převeden z fix14,4 na peníze. Přidání hodnoty 3 však vyžaduje další konverzi:
CONVERT(float(CONVERT(money, m))
Výraz XPath se vyhodnocuje jako:
CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)
Jak je ukázáno v následující tabulce, jedná se o stejnou konverzi, která se používá pro jiné výrazy XPath (například literály nebo složené výrazy).
| X není známo | X je struna | X je číslo | X je booleovský | |
|---|---|---|---|---|
| string(X) | KONVERTOVAT (nvarchar(4000), X, 126) | - | KONVERTOVAT (nvarchar(4000), X, 126) | PŘÍPAD, KDYŽ X PAK N'true' ELSE N'FALSE' KONEC |
| číslo(X) | KONVERTOVAT (float(53), X) | KONVERTOVAT (float(53), X) | - | PŘÍPAD, KDY X PAK 1 DALŠÍ 0 KONEC |
| boolean(X) | - | LEN(X) > 0 | X != 0 | - |
Examples
A. Převod datového typu v dotazu XPath
V následujícím dotazu XPath specifikovaném proti anotovanému schématu XSD dotaz vybere všechny uzly Employee s hodnotou atributu EmployeeID E-1, kde "E-" je prefix specifikovaný pomocí anotace sql:id.
Employee[@EmployeeID="E-1"]
Predikát v dotazu je ekvivalentní SQL výrazu:
N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'
Protože EmployeeID je jednou z hodnot datového typu id (idref, idrefs, nmtoken, nmtokens a podobně) v XSD schématu, EmployeeID je převedeno na řetězec XPath pomocí výše popsaných konverzních pravidel.
CONVERT(nvarchar(4000), Employees.EmployeeID, 126)
K řetězci se přidá předpona "E-" a výsledek se pak porovná s .N'E-1'
B. Proveďte několik převodů datových typů v dotazu XPath
Uvažujme tento dotaz XPath specifikovaný proti anotovanému schématu XSD: OrderDetail[@UnitPrice * @OrderQty > 98]
Tento dotaz XPath vrací všechny <prvky OrderDetail> splňující predikát @UnitPrice * @OrderQty > 98. Pokud je UnitPrice anotován datovým typem fix14.4 v anotovaném schématu, tento predikát je ekvivalentní SQL výrazu:
CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) * CONVERT(float(53), OrderDetail.OrderQty) > CONVERT(float(53), 98)
Při převodu hodnot v dotazu XPath první konverze převede datový typ XDR na typ XPath. Protože datový typ XSD UnitPrice je fix14.4, jak je popsáno v předchozí tabulce, jedná se o první použitou konverzi:
CONVERT(money, OrderDetail.UnitPrice))
Protože aritmetické operátory převádějí své operandy na číslo XPath datového typu, je použita druhá konverze (z jednoho XPath datového typu na jiný XPath), při které je hodnota převedena na float(53) (float(53) je blízko XPathova datového typu):
CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice))
Za předpokladu, že atribut OrderQty nemá XSD datový typ, je OrderQty převedena na číslo XPath datového typu v jedné konverzi:
CONVERT(float(53), OrderDetail.OrderQty)
Podobně se hodnota 98 převede na číslo datového typu XPath:
CONVERT(float(53), 98)
Poznámka:
Pokud je datový typ XSD použitý ve schématu nekompatibilní se základním datovým typem SQL Server v databázi, nebo pokud je provedena nemožná konverze datového typu XPath, SQL Server může vrátit chybu. Například pokud je atribut EmployeeID anotován anotací id-prefix , XPath Employee[@EmployeeID=1] generuje chybu, protože EmployeeID má anotaci id-prefix a nelze jej převést na číslo.