Richtlinien zum Verwenden von Methoden des xml-Datentyps

In diesem Thema werden Richtlinien zum Verwenden der xml-Datentypmethoden beschrieben.

Die PRINT-Anweisung

Die Methoden des xml-Datentyps können nicht in der PRINT-Anweisung verwendet werden, wie das folgende Beispiel zeigt. Die Methoden des xml-Datentyps werden als Unterabfragen behandelt, und Unterabfragen sind in der PRINT-Anweisung nicht zulässig. Aus diesem Grund gibt das folgende Beispiel einen Fehler zurück:

DECLARE @x xml
SET @x = '<root>Hello</root>'
PRINT @x.value('/root[1]', 'varchar(20)') -- will not work because this is treated as a subquery (select top 1 col from table) 

Eine mögliche Lösung besteht darin, zuerst das Ergebnis der value()-Methode einer Variablen vom xml-Typ zuzuweisen und dann diese Variable in der Abfrage anzugeben.

DECLARE @x xml
DECLARE @c varchar(max)
SET @x = '<root>Hello</root>'
SET @c = @x.value('/root[1]', 'varchar(11)')
PRINT @c                                                      

Die GROUP BY-Klausel

Die Methoden des xml-Datentyps werden intern als Unterabfragen behandelt. Da GROUP BY einen Skalarwert erfordert und keine Aggregate oder Unterabfragen zulässt, können Sie die Methoden des xml-Datentyps nicht in der GROUP BY-Klausel angeben. Eine mögliche Lösung besteht im Aufrufen einer benutzerdefinierten Funktion, innerhalb derer XML-Methoden verwendet werden.

Erstellen von Fehlerberichten

Sollte ein Fehler auftreten, lösen die Methoden des xml-Datentyps einen einzelnen Fehler im folgenden Format aus:

Msg errorNumber, Level levelNumber, State stateNumber:
XQuery [database.table.method]: description_of_error

Beispiel:

Msg 2396, Level 16, State 1:
XQuery [xmldb_test.xmlcol.query()]: Attribute may not appear outside of an element

Singleton-Überprüfungen

Positionsschritte, Funktionsparameter und Operatoren, die Singleton-Elemente benötigen, geben einen Fehler zurück, wenn der Compiler nicht ermitteln kann, ob zur Laufzeit ein Singleton-Element sichergestellt ist. Dieses Problem tritt häufig bei nicht typisierten Daten auf. So erfordert z. B. die Suche eines Attributs ein übergeordnetes Singleton-Element. Dabei ist eine Ordinalzahl ausreichend, die einen einzelnen übergeordneten Knoten auswählt. Die Auswertung einer node()-value()-Kombination zum Extrahieren von Attributwerten erfordert möglicherweise keine Angabe der Ordinalzahl. Dies ist im nächsten Beispiel dargestellt.

Beispiel: Bekanntes Singleton

In diesem Beispiel generiert die nodes()-Methode eine getrennte Zeile für jedes <book>-Element. Die value()-Methode, die für einen <book>-Knoten ausgewertet wird, extrahiert den Wert von @genre und ist – da es sich um ein Attribut handelt – ein Singleton.

SELECT nref.value('@genre', 'varchar(max)') LastName
FROM   T CROSS APPLY xCol.nodes('//book') AS R(nref)

Das XML-Schema wird zur Typprüfung von typisiertem XML verwendet. Wenn ein Knoten im XML-Schema als ein Singleton angegeben ist, verwendet der Compiler diese Informationen, und es tritt kein Fehler auf. Ansonsten ist eine Ordinalzahl erforderlich, die einen einzelnen Knoten auswählt. Insbesondere das Verwenden der descendant-or-self-Achse (//), wie z. B. in /book//title, führt zum Verlust des Singleton-Kardinalitätsrückschlusses für das <title>-Element, selbst wenn dieser vom XML-Schema angegeben ist. Deshalb sollten Sie ihn als (/book//title)[1] umschreiben.

Sie müssen sich des Unterschiedes zwischen //first-name[1] und (//first-name)[1] für die Typüberprüfung bewusst sein. Der erste Ausdruck gibt eine Sequenz von <first-name>-Knoten zurück, in denen jeder Knoten der am weitesten links befindliche <first-name>-Knoten innerhalb seiner gleichgeordneten Elemente ist. Der zweite Ausdruck gibt den ersten Singleton-<first-name>-Knoten in Dokumentreihenfolge in der XML-Instanz zurück.

Beispiel: Verwenden von value()

Die folgende Abfrage für eine nicht typisierte XML-Spalte führt zu einem statischen Kompilierungsfehler. Das liegt daran, dass value() einen Singleton-Knoten als das erste Argument erwartet und der Compiler nicht ermitteln kann, ob zur Laufzeit nur ein einzelner <last-name>-Knoten auftritt.

SELECT xCol.value('//author/last-name', 'nvarchar(50)') LastName
FROM   T

Es folgt eine Projektmappe, die Sie in Betracht ziehen könnten:

SELECT xCol.value('//author/last-name[1]', 'nvarchar(50)') LastName
FROM   T

Allerdings führt diese Projektmappe nicht zum Auflösen des Fehlers, weil mehrere <author>-Knoten in jeder XML-Instanz auftreten können. Die folgende umgeschriebene Version ist jedoch funktionsfähig:

SELECT xCol.value('(//author/last-name/text())[1]', 'nvarchar(50)') LastName
FROM   T

Diese Abfrage gibt den Wert des ersten <last-name>-Elements in jeder XML-Instanz zurück.

Siehe auch

Konzepte

Andere Ressourcen