Teilen über


XPath-Datentypen (SQLXML 4.0)

Gilt für: SQL Server Azure SQL-Datenbank

Microsoft SQL Server, XPath und XML-Schema (XSD) weisen sehr unterschiedliche Datentypen auf. XPath hat z. B. keine ganzzahligen Datentypen oder Datumstypen, aber SQL Server und XSD haben viele. XSD verwendet Nanosekundengenauigkeit für Zeitwerte, und SQL Server verwendet höchstens 1/300 Sekunden Genauigkeit. Einen Datentyp einem anderen zuzuordnen ist deshalb nicht immer möglich. Weitere Informationen zum Zuordnen von SQL Server-Datentypen zu XSD-Datentypen finden Sie unter "Datentypkoerionen" und "sql:datatype Annotation" (SQLXML 4.0).

XPath verfügt über drei Datentypen: Zeichenfolge, Zahl und boolescher Wert. Der Zahlendatentyp ist immer ein IEEE 754-Gleitkomma mit doppelter Genauigkeit. Der SQL Serverfloat(53)-Datentyp ist die am nächsten gelegene XPath-Zahl. Float(53) ist jedoch nicht genau IEEE 754. Zum Beispiel wird weder NaN (Not-a-Number) noch Unendlichkeit verwendet. Beim Versuch, eine nicht numerische Zeichenfolge in eine Zahl zu konvertieren, und der Versuch, durch Null zu dividieren, führt zu einem Fehler.

XPath-Konvertierungen

Wenn Sie eine XPath-Abfrage wie OrderDetail[@UnitPrice > "10.0"] verwenden, können implizite und explizite Datentypkonvertierungen den Sinn der Abfrage leicht verändern. Deshalb sollte nachvollzogen werden können, wie XPath-Datentypen implementiert werden. Die XPath-Sprachspezifikation, XML Path Language (XPath) Version 1.0 W3C Proposed Recommendation 8 Oktober 1999, finden Sie auf der W3C-Website unter http://www.w3.org/TR/1999/PR-xpath-19991008.html.

XPath-Operatoren werden in vier Kategorien unterteilt:

  • Boolesche Operatoren (AND, OR)

  • Relationale Operatoren (<, >= <, >=)

  • Gleichheitsoperatoren (=, !=)

  • Arithmetische Operatoren (+, -, *, DIV, MOD)

Bei jeder Operatorkategorie werden die Operanden auf andere Art und Weise konvertiert. XPath-Operatoren konvertieren ihre Operanden gegebenenfalls implizit. Arithmetische Operatoren konvertieren ihre Operanden in Zahl und führen zu einem Zahlenwert. Boolesche Operatoren konvertieren ihre Operanden in booleschen Wert und führen zu einem booleschen Wert. Relationale Operatoren und Gleichheitsoperatoren geben einen booleschen Wert aus. Allerdings verfügen sie, je nach dem ursprünglichen Datentyp ihrer Operanden, über unterschiedliche Konvertierungsregeln (siehe Tabelle).

Operand Relationaler Operator Gleichheitsoperator
Beide Operanden sind Knotensätze. TRUE, wenn und nur, wenn ein Knoten in einem Satz und ein Knoten im zweiten Satz vorhanden ist, sodass der Vergleich ihrer Zeichenfolgenwerte WAHR ist. Das gleiche.
Eine ist ein Knotensatz, der andere eine Zeichenfolge. TRUE, wenn und nur, wenn ein Knoten im Knotensatz vorhanden ist, sodass der Vergleich mit der in eine Zahl konvertierten Zeichenfolge WAHR ist. TRUE, wenn und nur, wenn ein Knoten im Knotensatz vorhanden ist, sodass beim Konvertieren in eine Zeichenfolge der Vergleich mit der Zeichenfolge WAHR ist.
Eine ist ein Knotensatz, der andere eine Zahl. TRUE, wenn und nur, wenn ein Knoten im Knotensatz vorhanden ist, sodass beim Konvertieren in Eine Zahl der Knoten der Vergleich mit der Zahl WAHR ist. Das gleiche.
Eine ist ein Knotensatz, der andere ein boolescher Wert. TRUE, wenn und nur, wenn ein Knoten im Knotensatz vorhanden ist, sodass beim Konvertieren in boolesche und dann in Zahl der Vergleich mit dem booleschen konvertierten Wert wahr ist. TRUE, wenn und nur, wenn ein Knoten im Knotensatz vorhanden ist, sodass beim Konvertieren in booleschen Wert der Vergleich mit dem booleschen Wert WAHR ist.
In beiden Fällen handelt es sich nicht um einen Knotensatz. Konvertieren Sie beide Operanden in Zahl , und vergleichen Sie dann. Konvertieren Sie beide Operanden in einen gängigen Typ , und führen Sie dann einen Vergleich durch. Konvertieren Sie in booleschen Wert, wenn eine der beiden booleschen Zahlen ist, wenn eine der Zahlen ist, andernfalls in eine Zeichenfolge konvertieren.

Hinweis

Da XPath-relationale Operatoren ihre Operanden immer in Zahlen konvertieren, sind Zeichenfolgenvergleiche nicht möglich. Um Datumsvergleiche einzuschließen, bietet SQL Server 2000 diese Variation der XPath-Spezifikation: Wenn ein relationaler Operator eine Zeichenfolge mit einer Zeichenfolge vergleicht, ein Knotensatz mit einer Zeichenfolge oder ein Zeichenfolgenwert-Knotensatz auf einen Zeichenfolgenwert-Knotensatz festgelegt wird, wird ein Zeichenfolgenvergleich (kein Zahlenvergleich ) ausgeführt.

Konvertierungen von Knotensätzen

Konvertierungen von Knotensätzen sind nicht immer intuitiv. Ein Knotensatz wird in eine Zeichenfolge konvertiert, indem der Zeichenfolgenwert nur des ersten Knotens im Satz verwendet wird. Ein Knotensatz wird in eine Zahl konvertiert, indem er in eine Zeichenfolge konvertiert und dann die Zeichenfolge in eine Zahl konvertiert wird. Ein Knotensatz wird in einen booleschen Wert konvertiert, indem er das Vorhandensein testet.

Hinweis

SQL Server führt keine Positionsauswahl für Knotensätze durch: Die XPath-Abfrage Customer[3] bedeutet z. B. den dritten Kunden; diese Art von Positionsauswahl wird in SQL Server nicht unterstützt. Daher werden die Konvertierungen von Node-set-to-string oder node-set-to-number, wie in der XPath-Spezifikation beschrieben, nicht implementiert. SQL Server verwendet "any"-Semantik, unabhängig davon, wo die XPath-Spezifikation die "erste" Semantik angibt. Beispielsweise wählt die XPath-Abfrage Order[OrderDetail/@UnitPrice > 10.0] basierend auf der W3C XPath-Spezifikation diese Bestellungen mit dem ersten OrderDetail aus, das einen UnitPrice größer als 10,0 aufweist. In SQL Server wählt diese XPath-Abfrage diese Bestellungen mit jedem OrderDetail aus, der einen UnitPrice größer als 10.0 aufweist.

Konvertierung in boolean generiert einen Existenztest. Daher entspricht die XPath-Abfrage Products[@Discontinued=true()] dem SQL-Ausdruck "Products.Discontinued is not null", nicht the SQL expression "Products.Discontinued = 1". Um die Abfrage mit dem letzten SQL-Ausdruck zu entsprechen, konvertieren Sie zuerst den Knotensatz in einen nicht booleschen Typ, z . B. "Zahl". Beispiel: Products[number(@Discontinued) = true()].

Da die meisten Operatoren gemäß Definition als TRUE gelten, wenn sie für einen beliebigen oder einen einzigen der Knoten im Knotensatz TRUE sind, ergeben diese Operationen stets FALSE, wenn der Knotensatz leer ist. Wenn also A leer ist, gilt sowohl für A = B als auch A != B FALSE, für not(A=B) und not(A!=B) hingegen gilt TRUE.

Normalerweise ist ein Attribut oder Element, das einer Spalte zugeordnet ist, vorhanden, wenn der Wert dieser Spalte in der Datenbank nicht NULL ist. Elemente, die auf Zeilen verweisen, sind vorhanden, sobald untergeordnete Elemente vorhanden sind.

Hinweis

Elemente, die mit "is-constant " versehen sind, sind immer vorhanden. Daher können XPath-Prädikate nicht für is-konstante Elemente verwendet werden.

Wenn ein Knotensatz in eine Zeichenfolge oder Zahl konvertiert wird, wird der XDR-Typ (falls vorhanden) im kommentierten Schema überprüft und dieser Typ verwendet, um die erforderliche Konvertierung zu ermitteln.

Zuordnung von XDR-Datentypen und XPath-Datentypen

Der XPath-Datentyp eines Knotens wird vom XDR-Datentyp im Schema abgeleitet, wie in der folgenden Tabelle dargestellt (der Knoten EmployeeID wird zur Veranschaulichung verwendet).

XDR-Datentyp Entsprechung

XPath-Datentyp
Verwendete SQL Server-Konvertierung
Nonebin.base64bin.hex N/V NoneEmployeeID
boolean boolean CONVERT(bit, EmployeeID)
number, int, float,i1, i2, i4, i8,r4, r8ui1, ui2, ui4, ui8 Zahl CONVERT(float(53), EmployeeID)
id, idref, idrefsentity, entities, enumerationnotation, nmtoken, nmtokens, chardate, Timedate, Time.tz, string, uri, uuid Zeichenfolge CONVERT(nvarchar(4000), EmployeeID, 126)
fixed14.4 – (es gibt keinen Datentyp in XPath, der dem fixed14.4 XDR-Datentyp entspricht) CONVERT(money, EmployeeID)
date Zeichenfolge LEFT(CONVERT(nvarchar(4000), EmployeeID, 126), 10)
time

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

Die Datums- und Uhrzeitkonvertierungen dienen dazu, zu funktionieren, ob der Wert in der Datenbank mithilfe des SQL Server-Datentyps"datetime " oder einer Zeichenfolge gespeichert wird. Beachten Sie, dass der DATENTYP "Datetime" von SQL Serverkeine Zeitzone verwendet und eine geringere Genauigkeit als der XML-Zeitdatentyp aufweist. Um den Zeitzonendatentyp oder zusätzliche Genauigkeit einzuschließen, speichern Sie die Daten in SQL Server mithilfe eines Zeichenfolgentyps .

Wenn ein Knoten vom XDR-Datentyp in den XPath-Datentyp konvertiert wird, müssen mitunter weitere Konvertierungen vorgenommen werden (von einem XPath-Datentyp in einen anderen XPath-Datentyp). Ein Beispiel ist die folgende XPath-Abfrage:

(@m + 3) = 4  

Wenn @m der XDR-Datentyp fixed14.4 entspricht, wird die Konvertierung vom XDR-Datentyp in den XPath-Datentyp mithilfe von:

CONVERT(money, m)  

In dieser Konvertierung wird der Knoten m von fixed14.4 in Geld konvertiert. Um den Wert 3 hinzuzufügen, ist jedoch eine zusätzliche Konvertierung erforderlich:

CONVERT(float(CONVERT(money, m))  

Der XPath-Ausdruck wird wie folgt ausgewertet:

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

Wie in der folgenden Tabelle dargestellt, handelt es sich hierbei um die gleiche Konvertierung wie bei anderen XPath-Ausdrücken (etwa Literalausdrücken oder zusammengesetzten Ausdrücken).

X ist unbekannt X ist Zeichenfolge X ist Zahl X ist boolescher Wert.
string(X) CONVERT (nvarchar(4000), X, 126) - CONVERT (nvarchar(4000), X, 126) CASE WHEN X THEN N'true' ELSE N'false' END
number(X) CONVERT (float(53), X) CONVERT (float(53), X) - CASE WHEN X THEN 1 ELSE 0 END
boolean(X) - LÄNGE(X) > 0 X != 0 -

Beispiele

A. Konvertieren Sie einen Datentyp in einer XPath-Abfrage

In der folgenden XPath-Abfrage, die für ein kommentiertes XSD-Schema angegeben wurde, wählt die Abfrage alle Mitarbeiterknoten mit dem Attributwert "EmployeeID " von E-1 aus, wobei "E-" das Präfix ist, das mit der sql:id-prefix-Anmerkung angegeben wird.

Employee[@EmployeeID="E-1"]

Das Prädikat in der Abfrage entspricht dem folgenden SQL-Ausdruck:

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

Da EmployeeID eine der Id-Werte (idref, idrefs, nmtoken, nmtokens usw.) im XSD-Schema ist, wird EmployeeID mithilfe der zuvor beschriebenen Konvertierungsregeln in den Zeichenfolgen-XPath-Datentyp konvertiert.

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

Der Zeichenfolge wird das Präfix "E-" hinzugefügt, und das Ergebnis wird dann mit N'E-1' verglichen.

B. Führen Sie mehrere Datentypkonvertierungen in einer XPath-Abfrage aus

Betrachten Sie die folgende, für ein mit Anmerkungen versehenes XSD-Schema angegebene XPath-Abfrage: OrderDetail[@UnitPrice * @OrderQty > 98]

Diese XPath-Abfrage gibt alle <OrderDetail-Elemente> zurück, die das Prädikat @UnitPrice * @OrderQty > 98erfüllen. Wenn " UnitPrice " mit einem "fixed14.4 "-Datentyp im kommentierten Schema kommentiert wird, entspricht dieses Prädikat dem SQL-Ausdruck:

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

Beim Konvertieren der Werte in der XPath-Abfrage wird zunächst der XDR-Datentyp in den XPath-Datentyp konvertiert. Da der XSD-Datentyp von UnitPrice fest14.4 ist, wie in der vorherigen Tabelle beschrieben, ist dies die erste Konvertierung, die verwendet wird:

CONVERT(money, OrderDetail.UnitPrice))   

Da die arithmetischen Operatoren ihre Operanden in den Datentyp "Zahl XPath" konvertieren, wird die zweite Konvertierung (von einem XPath-Datentyp in einen anderen XPath-Datentyp) angewendet, auf den der Wert in float(53) (float(53) konvertiert wird, dem XPath-Zahlendatentyp nahe kommt:

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

Wenn das OrderQty-Attribut keinen XSD-Datentyp aufweist, wird OrderQty in einen Zahlen-XPath-Datentyp in einer einzelnen Konvertierung konvertiert:

CONVERT(float(53), OrderDetail.OrderQty)  

Ebenso wird der Wert 98 in den Datentyp "XPath" konvertiert:

CONVERT(float(53), 98)  

Hinweis

Wenn der im Schema verwendete XSD-Datentyp mit dem zugrunde liegenden SQL Server-Datentyp in der Datenbank nicht kompatibel ist oder wenn eine unmögliche XPath-Datentypkonvertierung ausgeführt wird, gibt SQL Server möglicherweise einen Fehler zurück. Wenn beispielsweise das EmployeeID-Attribut mit id-präfixanmerkung versehen ist, generiert der XPath Employee[@EmployeeID=1] einen Fehler, da EmployeeID über die ID-Präfixanmerkung verfügt und nicht in eine Zahl konvertiert werden kann.