Freigeben über


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).

HinweisHinweis

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