value() メソッド (xml データ型)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

XML に対して XQuery を実行し、SQL 型の値を返します。 このメソッドは、スカラー値を返します。

このメソッドは、通常、xml 型の列、パラメーター、または変数に格納されている XML インスタンスから値を取得するために使用します。 このメソッドを使用すると、XML データと XML 型ではない列のデータを結合したり、比較する SELECT クエリを指定したりすることができます。

構文

value (XQuery, SQLType)  

Note

SQL Server 2014 (12.x) 以前のバージョンの Transact-SQL 構文を確認するには、以前のバージョンのドキュメントを参照してください。

引数

XQuery
XML インスタンス内のデータを取得する XQuery 式 (文字列リテラル) です。 XQuery により、返される値は最大 1 つである必要があります。 それ以外の場合は、エラーが返されます。

SQLType
正常な結果として返される SQL 型 (文字列リテラル) です。 このメソッドの戻り値の型は、SQLType パラメーターと一致します。 SQLType は、xml データ型、共通言語ランタイム (CLR) ユーザー定義型、imagetextntext、または sql_variant データ型にすることはできません。 SQLType には、SQL ユーザー定義データ型を指定できます。

value() メソッドでは、Transact-SQL の CONVERT 演算子を暗黙的に使用し、XQuery 式の結果 (シリアル化された文字列形式) を XSD 型から Transact-SQL 変換で指定されている対応する SQL 型に変換しようと試みます。 CONVERT の型キャストの規則の詳細については、「CAST および CONVERT (Transact-SQL)」を参照してください。

Note

パフォーマンス上の理由から、リレーショナル値との比較を行う述語内では value() メソッドではなく、exist()sql:column() を使用してください。 これは、下の例 D で示しています。

A. xml 型の変数に対する value() メソッドの使用

次の例では、XML インスタンスが xml 型の変数に格納されています。 value() メソッドは、XML から ProductID 属性の値を取得します。 その後、この値は int 変数に代入されます。

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  

値 1 が結果として返されます。

この場合、XML インスタンスに ProductID 属性は 1 つしかありませんが、静的な型指定の規則により、パス式がシングルトンを返すことを明示的に指定する必要があります。 このため、パス式の末尾に [1] が追加されています。 静的な型指定の詳細については、「XQuery と静的な型指定」を参照してください。

B. value() メソッドを使用した xml 型列の値の取得

次のクエリは、AdventureWorks データベースの xml 型の列 (CatalogDescription) に対して指定されています。 このクエリは、この列に格納されている各 XML インスタンスから ProductModelID 属性の値を取得します。

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             

上のクエリに関して、次の点に注意してください。

  • namespace キーワードを使用して名前空間プレフィックスが定義されています。

  • 静的な型指定の要件により、[1] メソッドのパス式の末尾に value() を追加して、パス式が単一の値を返すことを明示的に指定しています。

結果の一部を次に示します。

-----------  
35           
34           
...  

C. value() メソッドと exist() メソッドを使用した xml 型列の値の取得

次の例では、xml データ型の value() メソッドと exist() メソッドの使い方を示しています。 value() メソッドは、XML から ProductModelID 属性値を取得するために使用されます。 WHERE 句の exist() メソッドは、テーブルの行をフィルターで選択するために使用されています。

このクエリは、要素の 1 つとして保証内容 (<Warranty> 要素) を含む XML インスタンスから製品モデル ID を取得します。 WHERE 句の条件では、exist() メソッドを使用して、この条件を満たす行のみを取得しています。

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  

上のクエリに関して、次の点に注意してください。

  • CatalogDescription 列は、型指定された XML 列です。 つまり、この列にはスキーマ コレクションが関連付けられています。 XQuery プロローグでは、名前空間の宣言を使用して、後でクエリ本文で使用するプレフィックスを定義しています。

  • exist() メソッドが 1 (True) を返す場合、XML インスタンスには特性の 1 つとして <Warranty> 子要素が含まれています。

  • その場合は、value() 句の SELECT メソッドが、ProductModelID 属性の値を整数値として取得します。

結果の一部を次に示します。

Result       
-----------  
19           
23           
...  

D. value() メソッドの代替としての exist() メソッドの使用

パフォーマンス上の理由から、リレーショナル値との比較を行う述語内では value() メソッドではなく、exist()sql:column() を使用してください。 次に例を示します。

CREATE TABLE T (c1 INT, c2 VARCHAR(10), c3 XML)  
GO  
  
SELECT c1, c2, c3   
FROM T  
WHERE c3.value( '(/root[@a=sql:column("c1")]/@a)[1]', 'integer') = c1  
GO  

上記のクエリは、次のように記述することもできます。

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

参照

WITH XMLNAMESPACES を使用したクエリへの名前空間の追加
型指定された XML と型指定されていない XML の比較
XML データのインスタンスの作成
xml データ型メソッド
XML データ変更言語 (XML DML)