sp_describe_undeclared_parameters (Transact-SQL)
Transact-SQL バッチ内の宣言されていないパラメーターに関するメタデータを含む結果セットを返します。@tsql バッチ内で使用されており、@params で宣言されていない各パラメーターを対象として扱います。これらの各パラメーターに対して 1 行のデータを含む結果セットが返されます。そのパラメーターについて推論される型の情報も含まれます。 @tsql 入力バッチが @params で宣言されているパラメーター以外にパラメーターを持たない場合、このプロシージャは空の結果セットを返します。
適用対象: SQL Server (SQL Server 2012 から現在のバージョンまで)、Windows Azure 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 つを選択します。
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 つの暗黙的な変換が生成されます。
変換の数が最小となるデータ型が複数ある場合は、優先順位の高いデータ型が使用されます。 次に例を示します。
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 への暗黙的な変換は存在しません。
2 つの類似したデータ型 (たとえば varchar(8000) と varchar(max)) がルール 1 に該当する場合、小さい方のデータ型 (varchar(8000)) が選択されます。 nvarchar データ型および varbinary データ型にも同じ原則が適用されます。
ルール 1 のために、型推論アルゴリズムでは、特定の変換が他の変換よりも優先されます。 変換の優先順序は、次のとおりです。
長さの異なる同じ基本データ型間での変換。
同じデータ型の固定長バージョンと可変長バージョンの間の変換 (char から varchar への変換など)。
NULL と int の間の変換。
その他の変換。
たとえば、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)