value() -Methode (XML-Datentyp)

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed Instance

Führt eine XQuery anhand von XML aus und gibt einen Wert vom 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 Abfragen angeben SELECT , die XML-Daten mit Daten in Nicht-XML-Spalten kombinieren oder vergleichen.

Syntax

value ( XQuery , SQLType )

Hinweis

Informationen zum Anzeigen der Transact-SQL-Syntax für SQL Server 2014 (12.x) und früher finden Sie unter Dokumentation zu früheren Versionen.

Argumente

XQuery

Der XQuery-Ausdruck , ein Zeichenfolgenliteral, das Daten innerhalb der XML-Instanz abruft. Die XQuery muss mindestens einen Wert zurückgeben. Ansonsten wird ein Fehler zurückgegeben.

SQLType

Der bevorzugte SQL-Typ, ein Zeichenfolgenliteral, das zurückgegeben werden soll. Der Rückgabetyp dieser Methode entspricht dem SQLType -Parameter. SQLType kann kein XML-Datentyp , ein benutzerdefinierter Typ (Common Language Runtime, CLR) sein, kein benutzerdefinierter Typ, Einbild, Text, ntext oder sql_variant Datentyp. SQLType kann ein benutzerdefinierter SQL-Datentyp sein.

Die value() Methode verwendet implizit den Transact-SQL-Operator CONVERT . value() versucht, das Ergebnis des XQuery-Ausdrucks, der serialisierten Zeichenfolgendarstellung, vom XML-Schemadefinitionstyp (XSD) in den entsprechenden SQL-Typ zu konvertieren, der durch Transact-SQL-Konvertierung angegeben wird. Weitere Informationen zu Typ casting rules for CONVERT, see CAST and CONVERT.

Aus Leistungsgründen können Sie anstelle der value() Methode in einem Prädikat verwenden exist()sql:column(), um mit einem relationalen Wert zu vergleichen. Dieses exist() Beispiel wird weiter unten in diesem Artikel gezeigt.

Beispiele

Dieser Artikel erfordert die AdventureWorks2022-Beispieldatenbank, die Sie von der Homepage Microsoft SQL Server Samples and Community Projects herunterladen können.

A. Verwenden der Value()-Methode für eine XML-Typvariable

Im folgenden Beispiel wird eine XML-Instanz in einer Variablen vom XML-Typ gespeichert. Mit der value() -Methode wird der Wert des ProductID -Attributs aus der XML-Instanz abgerufen. Der Wert wird dann einer Int-Variable 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;

Ein Wert von 1 wird als Ergebnis zurückgegeben.

Obwohl in der XML-Instanz nur ein ProductID Attribut vorhanden ist, müssen Sie bei statischen Eingaberegeln explizit angeben, dass der Pfadausdruck ein Singleton zurückgibt. Daher wird das [1] Ende des Pfadausdrucks hinzugefügt. Weitere Informationen zur statischen Typisierung finden Sie unter XQuery and 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 AdventureWorks2022 -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="http://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;

Hinweis aus der vorherigen Abfrage:

  • 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. Verwenden Sie die Methoden value() und exist() zum Abrufen von Werten aus einer XML-Typspalte.

Das folgende Beispiel veranschaulicht die Verwendung 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.

Mit der Abfrage werden Produktmodell-IDs aus XML-Instanzen mit Garantieinformationen (<Warranty>-Element) als eine der Features abgerufen. 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="http://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="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     declare namespace wm="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";

     /PD:ProductDescription/PD:Features/wm:Warranty') = 1;

Hinweis aus der vorherigen Abfrage:

  • Die CatalogDescription -Spalte ist eine typisierte XML-Spalte. Das bedeutet, dass ihr eine Schemaauflistung zugeordnet ist. In den Modulen und Prologs – XQuery Prolog wird die Namespacedeklaration verwendet, um das Präfix zu definieren, das später im Abfragetext verwendet wird.

  • Wenn die exist() Methode zurückgibt 1 (true), gibt sie an, dass die XML-Instanz das <Warranty> untergeordnete Element als eines der Features enthält.

  • Die value() -Methode in der SELECT -Klausel ruft dann die ProductModelID -Attributwerte als ganze Zahlen ab.

Dies ist das Teilergebnis:

19
23
...

D: Verwenden Sie die exist()-Methode anstelle der Value()-Methode.

Aus Leistungsgründen sollten Sie zum Vergleichen mit einem relationalen Wert die value() -Methode mit exist() verwenden und nicht die sql:column()-Methode in einem Prädikat. Zum Beispiel:

CREATE TABLE T (c1 INT, c2 VARCHAR(10), c3 XML);
GO

SELECT c1, c2, c3
FROM T
WHERE c3.value('(/root/@a)[1]', 'integer') = c1;
GO

Dieser Code kann wie folgt umgeschrieben werden:

SELECT c1, c2, c3
FROM T
WHERE c3.exist('/root[@a=sql:column("c1")]') = 1;
GO