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 in 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 dervalue()
-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 in 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 eine1
(True) zurückgibt, bedeutet das, dass die XML-Instanz das untergeordnete <Warranty
>-Element als eines der Features einschließt. - Die
value()
-Methode in derSELECT
-Klausel ruft dann dieProductModelID
-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
Siehe auch
Konzepte
Hinzufügen von Namespaces mithilfe von WITH XMLNAMESPACES
Typisiertes im Vergleich zu nicht typisiertem XML
XML-Datentyp
Generieren von XML-Instanzen
XML DML (Data Modification Language)
XML-Beispielanwendungen