Typumwandlungsregeln in XQuery

Das folgende Spezifikationsdiagramm für Funktionen und Operatoren von W3C XQuery 1.0 und XPath 2.0 zeigt die integrierten Datentypen. Dies umfasst die integrierten primitiven und abgeleiteten Datentypen.

XQuery 1.0-Typhierarchie

In diesem Thema werden die Regeln für die Typumwandlung beschrieben, die beim Umwandeln von einem Typ in einen anderen mithilfe der folgenden Mehtoden angewendet werden:

  • Explizite Umwandlung, die mithilfe von cast as erfolgt.
  • Implizite Umwandlung, die während der Datentypheraufstufung auftritt.

Explizite Umwandlung

Die folgende Tabelle erläutert die zulässige Typumwandlung zwischen den integrierten primitiven Typen.

Umwandlungsregeln für XQuery

  • Ein integrierter primitiver Typ kann basierend auf den in der Tabelle aufgeführten Regeln in einen anderen integrierten primitiven Typ umgewandelt werden.
  • Ein primitiver Typ kann in jeden beliebigen Typ umgewandelt werden, der von diesem betreffenden primitiven Typ abgeleitet ist. Sie können z. B. eine Typumwandlung aus xs:decimal in xs:integer oder aus xs:decimal in xs:long durchführen.
  • Ein abgeleiteter Typ kann in einen beliebigen Typ umgewandelt werden, der sein Vorgänger in der Typhierarchie ist (bis hinauf zu seinem integrierten primitiven Basistyp). Sie können z. B. eine Typumwandlung aus xs:token in xs:normalizedString oder in xs:string durchführen.
  • Ein abgeleiteter Typ kann in einen primitiven Typ umgewandelt werden, wenn sein primitiver Vorgänger in den Zieltyp umgewandelt werden kann. Sie können z. B. xs:integer, einen abgeleiteten Typ, in xs:string, einen primitiven Typ, umwandeln, weil xs:decimal, der primitive Vorgänger von xs:integer, in xs:string umgewandelt werden kann.
  • Ein abgeleiteter Typ kann in einen anderen abgeleiteten Typ umgewandelt werden, wenn der primitive Vorgänger des Quelltyps in den primitiven Vorgänger des Zieltyps umgewandelt werden kann. Sie können z. B. eine Typumwandlung aus xs:integer in xs:token durchführen, weil xs:decimal in xs:string umgewandelt werden kann.
  • Die Regeln zum Umwandeln benutzerdefinierter Typen in integrierte Typen sind die gleichen wie für die integrierten Datentypen. Sie können z. B. einen myInteger-Datentyp definieren, der vom xs:integer-Typ abgeleitet ist. Anschließend kann für myInteger eine Typumwandlung in xs:token durchgeführt werden, weil xs:decimal in xs:string umgewandelt werden kann.

Die folgenden Datentypumwandlungsarten werden nicht unterstützt:

  • Die Typumwandlung in oder aus Listentypen ist nicht zulässig. Dies gilt sowohl für benutzerdefinierte Listentypen als auch für integrierte Listentypen wie z. B. xs:IDREFS, xs:ENTITIES und xs:NMTOKENS.
  • Die Typumwandlung in oder aus xs:QName ist nicht zulässig.
  • xs:NOTATION und die vollständig geordneten Untertypen von Duration xdt:yearMonthDuration und xdt:dayTimeDuration werden nicht unterstützt. Daher ist auch die Typumwandlung in oder aus diese(n) Datentypen nicht zulässig.

Die folgenden Beispiele veranschaulichen die explizite Typumwandlung.

Beispiel A

Das folgende Beispiel fragt eine Variable vom Typ xml ab. Die Abfrage gibt eine Sequenz eines Wertes vom simple-Typ zurück, der als xs:string typisiert ist.

declare @x xml
set @x = '<e>1</e><e>2</e>'
select @x.query('/e[1] cast as xs:string?')
go

Beispiel B

Das folgende Beispiel fragt eine typisierte xml-Variable ab. Das Beispiel erstellt zuerst eine XML-Schemaauflistung. Anschließend wird die XML-Schemaauflistung zum Erstellen einer typisierten xml-Variablen verwendet. Das Schema stellt die Typisierungsinformationen für die XML-Instanz bereit, die der Variablen zugeordnet ist. Anschließend werden Abfragen für die Variable angegeben.

create xml schema collection myCollection as N'
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="root">
            <xs:complexType>
                  <xs:sequence>
                        <xs:element name="A" type="xs:string"/>
                        <xs:element name="B" type="xs:string"/>
                        <xs:element name="C" type="xs:string"/>
                  </xs:sequence>
            </xs:complexType>
      </xs:element>
</xs:schema>'
go

Die folgende Abfrage gibt einen statischen Fehler zurück, weil nicht bekannt ist, wie viele <root>-Elemente der obersten Ebene in der Dokumentinstanz vorhanden sind.

declare @x xml(myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>
          <root><A>4</A><B>5</B><C>6</baz></C>'
select @x.query('/root/A cast as xs:string?')
go

Wenn ein Singleton-<root>-Element im Ausdruck angegeben wird, ist die Abfrage erfolgreich. Die Abfrage gibt eine Sequenz eines Wertes vom simple-Typ zurück, der als xs:string typisiert ist.

declare @x xml(myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>
              <root><A>4</A><B>5</B><C>6</C></root>'
select @x.query('/root[1]/A cast as xs:string?')
go

Im folgenden Beispiel enthält die Variable vom Typ xml ein document-Schlüsselwort, das die XML-Schemaauflistung angibt. Dies zeigt an, dass es sich bei der XML-Instanz um ein Dokument handeln muss, das ein einziges Element der obersten Ebene besitzt. Wenn Sie zwei <root>-Elemente in der XML-Instanz erstellen, wird ein Fehler zurückgegeben.

declare @x xml(document myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>
              <root><A>4</A><B>5</B><C>6</C></root>'
go

Sie können die Instanz so ändern, dass nur ein Element der obersten Ebene eingeschlossen wird. Die Abfrage funktioniert dann. Die Abfrage gibt erneut eine Sequenz eines Wertes vom simple-Typ zurück, der als xs:string typisiert ist.

declare @x xml(document myCollection)
set @x = '<root><A>1</A><B>2</B><C>3</C></root>'
select @x.query('/root/A cast as xs:string?')
go

Implizite Typumwandlung

Implizite Typumwandlung ist nur für numerische Datentypen und nicht typisierte atomare Datentypen zulässig. Die folgende min()-Funktion gibt z. B. den kleineren von zwei Werten zurück:

min(xs:integer("1"), xs:double("1.1"))

In diesem Beispiel weisen die beiden Werte, die an die XQuery min()-Funktion übergeben werden, unterschiedliche Datentypen auf. Auf diesem Grund wird implizite Konvertierung ausgeführt, wobei der integer-Typ auf double heraufgestuft wird und die beiden double-Werte verglichen werden.

Die Typheraufstufung, die in diesem Beispiel gezeigt wurde, unterliegt den folgenden Regeln:

  • Ein integrierter abgeleiteter numerischer Datentyp kann auf seinen Basistyp heraufgestuft werden. integer kann z. B. auf decimal heraufgestuft werden.
  • Ein decimal-Typ kann auf float und ein float-Typ auf double heraufgestuft werden.

Da implizite Typumwandlung nur für numerische Datentypen zulässig ist, sind die folgenden Vorgänge nicht zulässig.

  • Die implizite Typumwandlung für Zeichenfolgen-Datentypen ist nicht zulässig. Wenn z. B. zwei string-Datentypen erwartet werden und Sie einen string- und einen token-Datentyp übergeben, tritt keine implizite Typumwandlung auf, und es wird ein Fehler zurückgegeben.
  • Die implizite Typumwandlung aus numerischen Datentypen in Zeichenfolgen-Datentypen ist nicht zulässig. Wenn Sie z. B. einen Wert vom Typ integer an eine Funktion übergeben, die einen Parameter vom string-Typ erwartet, tritt keine implizite Typumwandlung auf, und es wird ein Fehler zurückgegeben.

Typumwandlung von Werten

Wenn eine Umwandlung von einem Datentyp in einen anderen erfolgt, werden die tatsächlichen Werte aus dem Wertebereich des Quelltyps in den Wertebereich des Zieltyps transformiert. Die Typumwandlung aus einem xs:decimal- in einen xs:double-Typ transformiert z. B. den decimal-Wert in einen double-Wert.

Im Folgenden finden Sie einige der Transformationsregeln.

Umwandeln eines Wertes aus einem string- oder untypedAtomic-Typ

Der Wert, der in einen string- oder untypedAtomic-Typ umgewandelt wird, wird auf die gleiche Weise wie beim Überprüfen des Wertes basierend auf den Regeln des Zieltyps transformiert. Dies schließt ggf. Muster- und Leerzeichenverarbeitungsregeln ein. Die folgende Umwandlung ist z. B. erfolgreich und generiert einen double-Wert (1.1e0):

xs:double("1.1")

Bei der Umwandlung in binäre Typen wie z. B. xs:base64Binary oder xs:hexBinary aus einem string- oder untypedAtomic-Typ müssen die Eingabewerte base64- bzw. hexadezimal codiert sein.

Umwandeln eines Wertes in einen string- oder untypedAtomic-Typ

Bei der Umwandlung eines string- oder untypedAtomic-Typs wird der Wert in die kanonische lexikalische Darstellung von XQuery transformiert. Dies kann insbesondere bedeuten, dass ein Wert, der während der Eingabe einem bestimmten Muster oder einer anderen Einschränkung unterworfen war, nicht gemäß dieser Einschränkung dargestellt wird. Damit Benutzer über diesen Konflikt informiert sind, markiert SQL Server 2005 zurzeit Typen, deren Typeinschränkung zu einem Problem werden kann, indem eine Warnung bereitgestellt wird, wenn diese Typen in die Schemaauflistung geladen werden.

Wenn ein Wert vom Typ xs:float oder xs:double oder einer ihrer Untertypen in einen string- oder untypedAtomic-Typ umgewandelt wird, wird der Wert in wissenschaftlicher Schreibweise dargestellt. Dies geschieht nur, wenn der Absolutwert des Wertes kleiner als 1.0E-6 oder größer oder gleich 1.0E6 ist. Dies bedeutet, dass 0 in wissenschaftlicher Schreibweise zu 0.0E0 serialisiert wird.

Beispielsweise gibt xs:string(1.11e1) den Zeichenfolgenwert "11.1" zurück, während xs:string(-0.00000000002e0) den Zeichenfolgenwert "-2.0E-11" zurückgibt.

Bei der Umwandlung binärer Typen wie z. B. xs:base64Binary oder xs:hexBinary in einen string- oder untypedAtomic-Typ werden die Binärwerte in base64- bzw. hexadezimal codierter Form dargestellt.

Umwandeln eines Wertes in einen numeric-Typ

Wenn ein Wert eines numeric-Typs in einen Wert eines anderen numeric-Typs umgewandelt wird, wird der Wert aus einem Wertebereich dem anderen Wertebereich zugeordnet, ohne die Zeichenfolgenserialisierung zu durchlaufen. Wenn der Wert nicht der Einschränkung eines Zieltyps genügt, gelten die folgenden Regeln:

  • Wenn der Quellwert bereits vom Typ numeric und der Zieltyp xs:float oder ein Untertyp davon ist, der -INF- oder INF-Werte zulässt, und die Typumwandlung des numeric-Quellwertes zu einem Überlauf führen würde, wird der Wert INF zugeordnet, wenn er positiv ist, oder -INF, wenn der Wert negativ ist. Wenn der Zieltyp keine INF- oder -INF-Werte zulässt und ein Überlauf auftreten würde, schlägt die Typumwandlung fehl. Das Ergebnis ist in dieser Version von SQL Server die leere Sequenz.
  • Wenn der Quellwert bereits vom Typ numeric und der Zieltyp ein numeric-Typ ist, der 0, -0e0 oder 0e0 im zulässigen Wertebereich enthält, und die Typumwandlung des numeric-Quellwertes einen Unterlauf verursachen würde, wird der Wert auf die folgende Weise zugeordnet:
    • Der Wert wird für einen decimal-Zieltyp 0 zugeordnet.
    • Der Wert wird -0e0 zugeordnet, wenn der Wert einen negativen Unterlauf verursacht.
    • Der Wert wird 0e0 zugeordnet, wenn der Wert einen negativen Unterlauf für einen float- oder double-Zieltyp verursacht.
      In SQL Server 2005 schlägt die Typumwandlung fehl, wenn der Zieltyp nicht Null in seinem Wertebereich enthält; das Ergebnis ist die leere Sequenz.
      Beachten Sie, dass durch die Umwandlung eines Wertes in einen binären Gleitkommawert wie z. B. xs:float, xs:double oder einen der jeweiligen Untertypen die Genauigkeit beeinträchtigt werden kann.

Implementierungseinschränkungen

Die folgenden Einschränkungen sind zu beachten:

  • Der Gleitkommawert NaN wird nicht unterstützt.

Siehe auch

Konzepte

Serialisierung von XML-Daten

Hilfe und Informationen

Informationsquellen für SQL Server 2005