sp_describe_undeclared_parameters (Transact-SQL)

Transact-SQL バッチ内の宣言されていないパラメーターに関するメタデータを含む結果セットを返します。@tsql バッチ内で使用されており、@params で宣言されていない各パラメーターを対象として扱います。これらの各パラメーターに対して 1 行のデータを含む結果セットが返されます。そのパラメーターについて推論される型の情報も含まれます。 @tsql 入力バッチが @params で宣言されているパラメーター以外にパラメーターを持たない場合、このプロシージャは空の結果セットを返します。

トピック リンク アイコン Transact-SQL 構文表記規則

構文

sp_describe_undeclared_parameters 
    [ @tsql = ] 'Transact-SQL_batch' 
    [ , [ @params = ] N'parameters' data type ] [, ...n]

引数

  • [ @tsql = ] 'Transact-SQL_batch'
    1 つ以上の Transact-SQL ステートメントです。 Transact-SQL_batch のデータ型には、nvarchar(n) または nvarchar(max) を指定できます。

  • [ @params = ] N'parameters'
    @params は、sp_executesql と同様に、Transact-SQL バッチのパラメーターの宣言文字列を提供します。 Parameters のデータ型には、nvarchar(n) または nvarchar(max) を指定できます。

    Transact-SQL_batch に埋め込まれたすべてのパラメーターの定義が含まれている 1 つの文字列を指定します。 この文字列は Unicode 定数または Unicode 変数にする必要があります。 各パラメーター定義は、パラメーター名とデータ型で構成されます。 n は、追加のパラメーター定義を示すプレースホルダーです。 Transact-SQL ステートメントまたはステートメント内のバッチにパラメーターが含まれていない場合、@params は不要です。 このパラメーターの既定値は NULL です。

  • Datatype
    パラメーターのデータ型です。

リターン コード値

sp_describe_undeclared_parameters は成功時に常に 0 のリターン ステータスを返します。 プロシージャが RPC として呼び出されていて、エラーをスローした場合、リターン ステータスには sys.dm_exec_describe_first_result_set の error_type 列に記述されているエラーの種類が設定されます。 プロシージャが Transact-SQL から呼び出されると、エラーの場合であっても戻り値は常に 0 です。

結果セット

sp_describe_undeclared_parameters は以下の結果セットを返します。

列名

データ型

説明

parameter_ordinal

int NOT NULL

結果セット内のパラメーターの位置を示す序数を格納します。 最初のパラメーターの位置は 1 で指定されます。

name

sysname NOT NULL

パラメーターの名前を格納します。

suggested_system_type_id

int NOT NULL

sys.types で指定されたパラメーターのデータ型の system_type_id を格納します。

CLR 型の場合は、system_type_name 列が NULL を返しても、この列は値 240 を返します。

suggested_system_type_name

nvarchar (256) NULL

データ型の名前を格納します。 パラメーターのデータ型に指定されている引数 (長さ、有効桁数、小数点以下桁数など) を含みます。 データ型がユーザー定義の別名型の場合は、基になるシステム型がここで指定されます。 データ型が CLR ユーザー定義型の場合は、この列には NULL が返されます。 パラメーターの型を推論できない場合は、NULL が返されます。

suggested_max_length

smallint NOT NULL

max_length 列の説明については、 「sys.columns」を参照してください。

suggested_precision

tinyint NOT NULL

precision 列の説明については、「sys.columns」を 参照してください。

suggested_scale

tinyint NOT NULL

scale 列の説明については、「sys.columns」を 参照してください。

suggested_user_type_id

int NULL

CLR 型と別名型の場合、sys.types で指定された列のデータ型の user_type_id を格納します。 それ以外の場合は NULL です。

suggested_user_type_database

sysname NULL

CLR 型と別名型の場合、その型が定義されたデータベースの名前を格納します。 それ以外の場合は NULL です。

suggested_user_type_schema

sysname NULL

CLR 型と別名型の場合、その型が定義されたスキーマの名前を格納します。 それ以外の場合は NULL です。

suggested_user_type_name

sysname NULL

CLR 型と別名型の場合、その型の名前を格納します。 それ以外の場合は NULL です。

suggested_assembly_qualified_type_name

nvarchar (4000) NULL

CLR 型の場合、その型を定義するアセンブリの名前とクラスを返します。 それ以外の場合は NULL です。

suggested_xml_collection_id

int NULL

sys.columns で指定されたパラメーターのデータ型の xml_collection_id を格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。

suggested_xml_collection_database

sysname NULL

この型に関連付けられている XML スキーマ コレクションが定義されているデータベースを格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。

suggested_xml_collection_schema

sysname NULL

この型に関連付けられている XML スキーマ コレクションが定義されているスキーマを格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。

suggested_xml_collection_name

sysname NULL

この型に関連付けられている XML スキーマ コレクションの名前を格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。

suggested_is_xml_document

bit NOT NULL

返されたデータ型が XML で、その型が XML ドキュメントであると保証される場合、1 を返します。 それ以外の場合は 0 を返します。

suggested_is_case_sensitive

bit NOT NULL

この列が大文字と小文字を区別する文字列型の場合は 1、それ以外の場合は 0 を返します。

suggested_is_fixed_length_clr_type

bit NOT NULL

この列が固定長の CLR 型の場合は 1、それ以外の場合は 0 を返します。

suggested_is_input

bit NOT NULL

パラメーターが、代入の左辺以外の場所で使用される場合は 1 を返します。 それ以外の場合は 0 を返します。

suggested_is_output

bit NOT NULL

パラメーターが代入の左辺で使用される場合、またはストアド プロシージャの出力パラメーターに渡される場合は 1 を返します。 それ以外の場合は 0 を返します。

formal_parameter_name

sysname NULL

パラメーターがストアド プロシージャまたはユーザー定義関数の引数の場合は、対応する仮パラメーターの名前を返します。 それ以外の場合は NULL を返します。

suggested_tds_type_id

int NOT NULL

内部使用です。

suggested_tds_length

int NOT NULL

内部使用です。

説明

sp_describe_undeclared_parameters は常に 0 のリターン ステータスを返します。

最も一般的な使用方法は、パラメーターを含み、それらのパラメーターを任意の方法で処理する必要がある Transact-SQL ステートメントがアプリケーションで指定される場合です。 たとえば、ユーザーが ODBC パラメーターの構文に基づくクエリを提供するユーザー インターフェイス (ODBCTest または RowsetViewer など) があります。 このような場合、アプリケーションは動的にパラメーターの数を検出し、それぞれのパラメーターに対してユーザーに入力を求める必要があります。

別の例として、ユーザーによる入力は行わずに、アプリケーションがパラメーターをループして、各パラメーターのデータを他の場所 (テーブルなど) から取得する必要がある場合が挙げられます。この場合、アプリケーションはすべてのパラメーター情報を一度に渡す必要はありません。 代わりに、アプリケーションはプロバイダーからすべてのパラメーター情報を取得し、データ自体はテーブルから取得することができます。 sp_describe_undeclared_parameters を使用したコードはより汎用的で、データ構造が後で変更された場合でも、修正が必要となることがあまりありません。

sp_describe_undeclared_parameters は、次のいずれかの場合にエラーを返します。

  • 入力の @tsql が有効な Transact-SQL バッチではない場合。 有効性は、Transact-SQL バッチの解析および分析によって判別されます。 クエリの最適化中または実行中にバッチが原因で発生したエラーは、Transact-SQL バッチが有効かどうかを決定する際には考慮されません。

  • @params が NULL ではなく、構文的に有効なパラメーターの宣言文字列ではない文字列を含む場合、またはパラメーターを複数回宣言する文字列を含む場合。

  • 入力の Transact-SQL バッチが、@params で宣言されたパラメーターと同じ名前のローカル変数を宣言した場合。

  • ステートメントによって一時テーブルが作成される場合。

@tsql@params で宣言されているパラメーター以外にパラメーターを持たない場合、このプロシージャは空の結果セットを返します。

パラメーター選択アルゴリズム

宣言されていないパラメーターを持つクエリの場合、宣言されていないパラメーターのデータ型の推論は 3 つの手順で実行されます。

手順 1

宣言されていないパラメーターを持つクエリのデータ型の推論の最初の手順は、宣言されていないパラメーターに依存しないデータ型を持つすべてのサブ式のデータ型を見つけることです。 型は次の式に対して特定できます。

  • 列、定数、変数、および宣言されたパラメーター。

  • ユーザー定義関数 (UDF) の呼び出しの結果。

  • すべての入力について、宣言されていないパラメーターに依存しないデータ型を持つ式。

たとえば、SELECT dbo.tbl(@p1) + c1 FROM t1 WHERE c2 = @p2 + 2 というクエリについて考えてみます。 式 dbo.tbl(@p1) + c1 と c2 にはデータ型があり、式 @p1@p2 + 2 にはデータ型がありません。

この手順の実行後、UDF の呼び出し以外の任意の式に、データ型のない 2 つの引数が含まれている場合、型推論はエラーで失敗します。 たとえば、次のすべての式ではエラーが発生します。

SELECT * FROM t1 WHERE @p1 = @p2
SELECT * FROM t1 WHERE c1 = @p1 + @p2
SELECT * FROM t1 WHERE @p1 = SUBSTRING(@p2, 2, 3)

次の例ではエラーは発生しません。

SELECT * FROM t1 WHERE @p1 = dbo.tbl(c1, @p2, @p3)

手順 2

指定された宣言されていないパラメーター @p の場合、型推論アルゴリズムは、@p を含み、以下のいずれかである最も内側の式 E(@p) を探します。

  • 比較演算子または代入演算子の引数。

  • ユーザー定義関数 (テーブル値 UDF を含む)、プロシージャ、またはメソッドの引数。

  • INSERT ステートメントの VALUES 句の引数。

  • CAST または CONVERT の引数。

型推論アルゴリズムは、E(@p) について対象のデータ型 TT(@p) を探します。 前の例の場合、対象のデータ型は以下のとおりです。

  • 比較または代入の反対側のデータ型。

  • この引数が渡されるパラメーターの宣言されたデータ型。

  • この値が挿入される列のデータ型。

  • このステートメントがキャストまたは変換するデータ型。

たとえば、SELECT * FROM t WHERE @p1 = dbo.tbl(@p2 + c1) というクエリについて考えてみます。 E(@p1) = @p1、E(@p2) = @p2 + c1、TT(@p1) は dbo.tbl の宣言された戻り値のデータ型であり、TT(@p2) は dbo.tbl の宣言されたパラメーターのデータ型です。

@p が手順 2. の冒頭に記載されたどの式にも該当しない場合、型推論アルゴリズムは E(@p) が @p を含む最大のスカラー式であると判断し、E(@p) の対象のデータ型 TT(@p) を計算しません。 たとえば、クエリ が SELECT @p + 2 の場合、E(@p) = @p + 2 で、TT(@p) はありません。

手順 3

E(@p) と TT(@p) が特定されたので、型推論アルゴリズムは @p のデータ型を次の 2 つの方法のいずれかで推論します。

  • 単純な推論

    E(@p) = @p で TT(@p) が存在する場合、つまり @p が直接、手順 2. の冒頭に記載されたいずれかの式の引数になる場合、型推論アルゴリズムは @p のデータ型が TT(@p) であると推論します。 次に例を示します。

    SELECT * FROM t WHERE c1 = @p1 AND @p2 = dbo.tbl(@p3)
    

    @p1、@p2、@p3 のデータ型はそれぞれ、c1 のデータ型、dbo.tbl の戻り値のデータ型、dbo.tbl のパラメーターのデータ型になります。

    特別なケースとして、@p が <、>、<=、または >= 演算子の引数である場合、単純な推論のルールは適用されません。 型推論アルゴリズムは、次のセクションで説明する一般的な推論のルールを使用します。 たとえば、c1 がデータ型 char(30) の列である場合に、以下の 2 つのクエリについて考えてみます。

    SELECT * FROM t WHERE c1 = @p
    SELECT * FROM t WHERE c1 > @p
    

    1 つ目のクエリでは、型推論アルゴリズムはこのトピックで説明したルールにより、char(30) が @p のデータ型であると推論します。 2 つ目のクエリでは、型推論アルゴリズムは次のセクションの一般的な推論のルールに従って、データ型が varchar(8000) であると推論します。

  • 一般的な推論

    単純な推論が適用されない場合、次のデータ型は宣言されていないパラメーターと見なされます。

    • 整数データ型 (bit、tinyint、smallint、int、bigint)

    • Money データ型 (smallmoney、money)

    • 浮動小数点データ型 (float、real)

    • numeric(38, 19) - その他の数値データ型または decimal データ型は考慮されません。

    • varchar(8000)、varchar(max)、nvarchar(4000)、および nvarchar(max) - その他の文字列データ型 (text、char(8000)、nvarchar(30) など) は考慮されません。

    • varbinary(8000) および varbinary(max) - その他のバイナリ データ型 (image、binary(8000)、varbinary(30) など) は考慮されません。

    • date、time(7)、smalldatetime、datetime、datetime2(7)、datetimeoffset(7) - その他の日付と時刻のデータ型 (time(4) など) は考慮されません。

    • sql_variant

    • xml

    • CLR システム定義型 (hierarchyid、geometry、geography)

    • CLR ユーザー定義型

選択基準

候補のデータ型のうち、クエリを無効にするデータ型は拒否されます。 候補の残りのデータ型から、型推論アルゴリズムが次のルールに従って 1 つを選択します。

  1. E(@p) で生成される暗黙的な変換の数が最小となるデータ型が選択されます。 特定のデータ型が、E(@p) に対して TT(@p) とは異なるデータ型を生成する場合、型推論アルゴリズムはこれを E(@p) のデータ型から TT(@p) への余分な暗黙的変換と見なします。

    次に例を示します。

    SELECT * FROM t WHERE Col_Int = Col_Int + @p
    

    この場合、E(@p) は Col_Int + @p であり、TT(@p) は int です。 暗黙的な変換が生成されないため、@p には int が選択されます。 その他のデータ型を選択すると、少なくとも 1 つの暗黙的な変換が生成されます。

  2. 変換の数が最小となるデータ型が複数ある場合は、優先順位の高いデータ型が使用されます。 次に例を示します。

    SELECT * FROM t WHERE Col_Int = Col_smallint + @p
    

    この場合、int と smallint が 1 つの変換を生成します。 他のすべてのデータ型では、2 つ以上の変換が生成されます。 int は smallint よりも優先されるので、@p には int が使用されます。 データ型の優先順位の詳細については、「データ型の優先順位 (Transact-SQL)」を参照してください。

    このルールは、ルール 1 に該当するすべてのデータ型と、最高位の優先順位を持つデータ型との間に暗黙的な変換がある場合にのみ適用されます。 暗黙的な変換がない場合、データ型の推論はエラーで失敗します。 たとえば、クエリ SELECT @p FROM t では、@p に対してすべてのデータ型の優先順位が同等であるため、型推論は失敗します。 また、int から xml への暗黙的な変換は存在しません。

  3. 2 つの類似したデータ型 (たとえば varchar(8000) と varchar(max)) がルール 1 に該当する場合、小さい方のデータ型 (varchar(8000)) が選択されます。 nvarchar データ型および varbinary データ型にも同じ原則が適用されます。

  4. ルール 1 のために、型推論アルゴリズムでは、特定の変換が他の変換よりも優先されます。 変換の優先順序は、次のとおりです。

    1. 長さの異なる同じ基本データ型間での変換。

    2. 同じデータ型の固定長バージョンと可変長バージョンの間の変換 (char から varchar への変換など)。

    3. NULL と int の間の変換。

    4. その他の変換。

たとえば、SELECT * FROM t WHERE [Col_varchar(30)] > @p の場合、変換 (a) の優先度が最も高いため、varchar(8000) が選択されます。 クエリ SELECT * FROM t WHERE [Col_char(30)] > @p の場合も、やはり varchar(8000) が選択されます。この場合の変換の種類は (b) であり、他の選択肢 (varchar(4000) など) は (d) になるためです。

最後の例として、クエリ SELECT NULL + @p の場合は、(c) の変換に該当するため、@p には int が選択されます。

権限

引数 @tsql を実行する権限が必要です。

使用例

次の例は、宣言されていない @id パラメーターおよび @name パラメーターに対して予期されるデータ型などの情報を返します。

sp_describe_undeclared_parameters @tsql = 
N'SELECT object_id, name, type_desc 
FROM sys.indexes
WHERE object_id = @id OR name = @name'

@id パラメーターが @params 参照として指定された場合は、@id パラメーターは結果セットから省略され、@name パラメーターのみが記述されます。

sp_describe_undeclared_parameters @tsql = 
N'SELECT object_id, name, type_desc 
FROM sys.indexes
WHERE object_id = @id OR NAME = @name',
@params = N'@id int'

関連項目

参照

sp_describe_first_result_set (Transact-SQL)

sys.dm_exec_describe_first_result_set (Transact-SQL)

sys.dm_exec_describe_first_result_set_for_object (Transact-SQL)