Typensystem (XQuery)
XQuery ist eine streng typisierte Sprache für Schematypen und eine schwach typisierte Sprache für nicht typisierte Daten. Zu den vordefinierten Typen von XQuery zählen folgende Typen:
Integrierte Typen des XML-Schemas im **http://www.w3.org/2001/XMLSchema**-Namespace.
Typen, die im **http://www.w3.org/2004/07/xpath-datatypes**-Namespace definiert sind.
In diesem Thema wird auch Folgendes beschrieben:
Der Unterschied zwischen dem typisierten Wert und dem Zeichenfolgenwert eines Knotens.
Die data-Funktion (XQuery) und die string-Funktion (XQuery).
Zuordnen des von einem Ausdruck zurückgegebenen Sequenztyps
Integrierte Typen des XML-Schemas
Die integrierten Typen des XML-Schemas besitzen das vordefinierte Namespacepräfix xs. Einige dieser Typen schließen xs:integer und xs:string ein. Alle diese integrierten Typen werden unterstützt. Sie können diese Typen verwenden, wenn Sie eine XML-Schemaauflistung erstellen.
Beim Abfragen von typisiertem XML-Code wird der statische und dynamische Typ der Knoten durch die XML-Schemaauflistung bestimmt, die der abgefragten Spalte oder Variablen zugeordnet ist. Weitere Informationen zu statischen und dynamischen Typen finden Sie unter Ausdruckskontext und Ausdrucksauswertung (XQuery). Die folgende Abfrage wird z. B. für eine typisierte xml-Spalte (Instructions) angegeben. Der Ausdruck verwendet instance of, um zu überprüfen, ob der typisierte Wert des zurückgegebenen LotSize-Attributs den xs:decimal-Typ aufweist.
SELECT Instructions.query('
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
data(/AWMI:root[1]/AWMI:Location[@LocationID=10][1]/@LotSize)[1] instance of xs:decimal
') AS Result
FROM Production.ProductModel
WHERE ProductModelID=7
Diese Typisierungsinformationen werden durch die XML-Schemaauflistung bereitgestellt, die der Spalte zugeordnet sind. Weitere Informationen finden Sie unter Darstellung des xml-Datentyps in der AdventureWorks-Datenbank.
Im Namespace für XPath-Datentypen definierte Typen
Die im **http://www.w3.org/2004/07/xpath-datatypes**-Namespace definierten Typen besitzen das vordefinierte Präfix xdt. Für diese Typen gilt Folgendes:
Sie können diese Typen nicht verwenden, wenn Sie eine XML-Schemaauflistung erstellen. Diese Typen werden im XQuery-Typisierungssystem verwendet und für die XQuery und statische Typisierung genutzt. Sie können eine Umwandlung in die atomaren Typen, z. B. von xdt:untypedAtomic, im xdt-Namespace durchführen.
Beim Abfragen von nicht typisiertem XML-Code ist der statische und dynamische Typ der Elementknoten xdt:untyped, und der Typ der Attributwerte ist xdt:untypedAtomic. Das Ergebnis einer query()-Methode generiert nicht typisierten XML-Code. Das bedeutet, dass die XML-Knoten als xdt:untyped bzw. als xdt:untypedAtomic zurückgegeben werden.
Die Typen xdt:dayTimeDuration und xdt:yearMonthDuration werden nicht unterstützt.
Im folgenden Beispiel wird die Abfrage für eine nicht typisierte XML-Variable angegeben. Der Ausdruck data(/a[1]) gibt eine Sequenz eines atomaren Werts zurück. Die data()-Funktion gibt den typisierten Wert des <a>-Elements zurück. Da der abgefragte XML-Code nicht typisiert ist, ist der Typ des zurückgegebenen Werts xdt:untypedAtomic. Deshalb gibt instance of den Wert True zurück.
DECLARE @x xml
SET @x='<a>20</a>'
SELECT @x.query( 'data(/a[1]) instance of xdt:untypedAtomic' )
Statt den typisierten Wert abzurufen, gibt der Ausdruck (/a[1]) im folgenden Beispiel eine Sequenz aus einem Element (dem <a>-Element) zurück. Der instance of-Ausdruck verwendet den Elementtest, um zu überprüfen, ob der vom Ausdruck zurückgegebene Wert ein xdt:untyped type-Elementknoten ist.
DECLARE @x xml
SET @x='<a>20</a>'
-- Is this an element node whose name is "a" and type is xdt:untyped.
SELECT @x.query( '/a[1] instance of element(a, xdt:untyped?)')
-- Is this an element node of type xdt:untyped.
SELECT @x.query( '/a[1] instance of element(*, xdt:untyped?)')
-- Is this an element node?
SELECT @x.query( '/a[1] instance of element()')
Hinweis |
---|
Wenn Sie eine typisierte XML-Instanz abfragen und der Abfrageausdruck schließt die übergeordnete Achse ein, sind die Informationen zum statischen Typ der resultierenden Knoten nicht weiter verfügbar. Der dynamische Typ ist jedoch weiterhin den Knoten zugeordnet. |
Typisierter Wert im Vergleich zum Zeichenfolgenwert
Jeder Knoten besitzt einen typisierten Wert und einen Zeichenfolgenwert. Für typisierte XML-Daten wird der Typ des typisierten Werts durch die XML-Schemaauflistung bereitgestellt, die der abgefragten Spalte oder Variablen zugeordnet ist. Für nicht typisierte XML-Daten ist der Typ des typisierten Werts xdt:untypedAtomic.
Sie können die data()- oder string()-Funktion verwenden, um den Wert eines Knotens abzurufen.
Die data-Funktion (XQuery) gibt den typisierten Wert eines Knotens zurück.
Die string-Funktion (XQuery) gibt den Zeichenfolgenwert des Knotens zurück.
In der folgenden XML-Schemaauflistung ist das <root>-Element des ganzzahligen Datentyps definiert:
CREATE XML SCHEMA COLLECTION SC AS N'
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="root" type="integer"/>
</schema>'
GO
Im folgenden Beispiel ruft der Ausdruck zuerst den typisierten Wert von /root[1] ab und fügt ihm anschließend 3 hinzu.
DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('data(/root[1]) + 3')
Im nächsten Beispiel schlägt der Ausdruck fehl, weil die string(/root[1])-Anweisung im Ausdruck einen Wert des Zeichenfolgentyps zurückgibt. Dieser Wert wird dann an einen arithmetischen Operator übergeben, der nur Werte des numerischen Typs als Operand akzeptiert.
-- Fails because the argument is string type (must be numeric primitive type).
DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('string(/root[1]) + 3')
Im folgenden Beispiel wird der Gesamtwert der LaborHours-Attribute berechnet. Die data()-Funktion ruft die typisierten Werte der LaborHours -Attribute aus allen <Location>-Elementen für ein Produktmodell ab. Entsprechend dem XML-Schema, das der Instruction-Spalte zugeordnet ist, weist LaborHours den xs:decimal-Typ auf.
SELECT Instructions.query('
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
sum(data(//AWMI:Location/@LaborHours))
') AS Result
FROM Production.ProductModel
WHERE ProductModelID=7
Diese Abfrage gibt 12.75 als Ergebnis zurück.
Hinweis |
---|
Die explizite Verwendung der data()-Funktion in diesem Beispiel dient lediglich der Veranschaulichung. Wenn sie nicht angegeben wird, wendet sum() implizit die data() an, um die typisierten Werte der Knoten zu extrahieren. |