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

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

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

構文

value (XQuery, SQLType)

引数

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

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

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

注意注意

パフォーマンス上の理由から、リレーショナル値との比較を行う述語内では 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="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           

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

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

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

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

-----------
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="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

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

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

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

  • その場合は、SELECT 句の value() メソッドが、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[1]/@a', 'integer') = c1
GO

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

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