value()-Methode (xml-Datentyp)
Führt eine XQuery-Abfrage für den XML-Code aus und gibt einen Wert im SQL-Typ zurück. Diese Methode gibt einen Skalarwert zurück.
Sie verwenden diese Methode üblicherweise, um einen Wert aus einer XML-Instanz zu extrahieren, die in einer Spalte, einem Parameter oder einer Variablen des xml-Datentyps gespeichert ist. Auf diese Weise können Sie SELECT-Abfragen angeben, die XML-Daten mit Daten in Nicht-XML-Spalten kombinieren oder vergleichen.
Syntax
value (XQuery, SQLType)
Argumente
XQuery
Ist der XQuery-Ausdruck (ein Zeichenfolgenliteral), der Daten innerhalb der XML-Instanz abruft. Die XQuery muss mindestens einen Wert zurückgeben. Ansonsten wird ein Fehler zurückgegeben.SQLType
Ist der bevorzugte SQL-Typ (ein Zeichenfolgenliteral), der zurückgegeben werden soll. Der Rückgabetyp dieser Methode stimmt mit dem SQLType-Parameter überein. SQLType darf kein xml-Datentyp, CLR-benutzerdefinierter Typ (Common Language Runtime), image-, text-, ntext- oder sql_variant-Datentyp sein. SQLType kann ein benutzerdefinierter SQL-Datentyp sein.
Die value()-Methode verwendet implizit den Transact-SQL-Operator CONVERT und versucht, das Ergebnis des XQuery-Ausdrucks (die serialisierte Zeichenfolgendarstellung) vom XSD-Typ in den entsprechenden SQL-Typ zu konvertieren, der durch die Transact-SQL-Konvertierung angegeben wird. Weitere Informationen zu den Regeln zur Typumwandlung für CONVERT finden Sie unter CAST und CONVERT (Transact-SQL).
Hinweis |
---|
Aus Leistungsgründen sollten Sie zum Vergleichen mit einem relationalen Wert die exist()-Methode mit sql:column() verwenden und nicht die value()-Methode in einem Prädikat. Dies wird im folgenden Beispiel D gezeigt. |
Beispiele
A. Verwenden der value()-Methode für eine xml-Typvariable
Im folgenden Beispiel ist eine XML-Instanz in einer Variablen des xml-Typs gespeichert. Mit der value()-Methode wird der Wert des ProductID-Attributs aus der XML-Instanz abgerufen. Dieser Wert wird dann einer int-Variablen zugewiesen.
DECLARE @myDoc xml
DECLARE @ProdID int
SET @myDoc = '<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>
<Warranty>1 year parts and labor</Warranty>
<Maintenance>3 year parts and labor extended maintenance is available</Maintenance>
</Features>
</ProductDescription>
</Root>'
SET @ProdID = @myDoc.value('(/Root/ProductDescription/@ProductID)[1]', 'int' )
SELECT @ProdID
Als Ergebnis wird Wert 1 zurückgegeben.
Obwohl es nur ein ProductID-Attribut in der XML-Instanz gibt, müssen Sie aufgrund der statischen Typisierungsregeln explizit angeben, dass der Pfadausdruck ein Singleton zurückgibt. Deshalb wird zusätzlich [1] am Ende des Pfadausdrucks angegeben. Weitere Informationen zur statischen Typisierung finden Sie unter XQuery und statische Typisierung.
B. Verwenden der value()-Methode zum Abrufen eines Werts aus einer xml-Typspalte
Die folgende Abfrage wird für eine Spalte vom Typ xml (CatalogDescription) in der AdventureWorks-Datenbank angegeben. Die Abfrage ruft die Werte des Attributs ProductModelID aus jeder in der Spalte gespeicherten XML-Instanz ab.
SELECT CatalogDescription.value('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
(/PD:ProductDescription/@ProductModelID)[1]', 'int') AS Result
FROM Production.ProductModel
WHERE CatalogDescription IS NOT NULL
ORDER BY Result desc
Beachten Sie hinsichtlich der vorherigen Abfrage Folgendes:
Das namespace-Schlüsselwort wird verwendet, um ein Namespacepräfix zu definieren.
Gemäß den Anforderungen der statischen Typisierung wird [1] am Ende des Pfadausdrucks in der value()-Methode hinzugefügt, um explizit anzugeben, dass der Pfadausdruck ein Singleton zurückgibt.
Dies ist das Teilergebnis:
-----------
35
34
...
C. Verwendung der Methoden value() und exist() zum Abrufen von Werten aus einer xml-Typspalte
Das folgende Beispiel veranschaulicht das Verwenden der beiden Methoden value() und exist() des xml-Datentyps. Die value()-Methode wird zum Abrufen von ProductModelID-Attributwerten aus der XML-Instanz verwendet. Mit der exist()-Methode in der WHERE-Klausel werden die Zeilen aus der Tabelle gefiltert.
Die Abfrage ruft Produktmodell-IDs aus XML-Instanzen ab, die Garantieinformationen (das <Warranty>-Element) als eines der Features enthält. Die Bedingung in der WHERE-Klausel verwendet die exist()-Methode, um nur solche Zeilen abzurufen, die diese Bedingung erfüllen.
SELECT CatalogDescription.value('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
(/PD:ProductDescription/@ProductModelID)[1] ', 'int') as Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";
/PD:ProductDescription/PD:Features/wm:Warranty ') = 1
Beachten Sie hinsichtlich der vorherigen Abfrage Folgendes:
Die CatalogDescription-Spalte ist eine typisierte XML-Spalte. Das bedeutet, dass ihr eine Schemaauflistung zugeordnet ist. Im XQuery-Prolog wird die Namespacedeklaration verwendet, um das Präfix zu definieren, das später im Body-Teil der Abfrage verwendet wird.
Wenn die exist()-Methode eine 1 (True) zurückgibt, bedeutet das, dass die XML-Instanz das untergeordnete <Warranty>-Element als eines der Features einschließt.
Die value()-Methode in der SELECT-Klausel ruft dann die ProductModelID-Attributwerte als ganze Zahlen ab.
Dies ist das Teilergebnis:
Result
-----------
19
23
...
D. Verwenden der exist()-Methode anstelle der value()-Methode
Aus Leistungsgründen sollten Sie zum Vergleichen mit einem relationalen Wert die exist()-Methode mit sql:column() verwenden und nicht die value()-Methode in einem Prädikat. Beispiel:
CREATE TABLE T (c1 int, c2 varchar(10), c3 xml)
GO
SELECT c1, c2, c3
FROM T
WHERE c3.value( '/root[1]/@a', 'integer') = c1
GO
Dies kann in der folgenden Weise geschrieben werden:
SELECT c1, c2, c3
FROM T
WHERE c3.exist( '/root[@a=sql:column("c1")]') = 1
GO