sp_describe_first_result_set (Transact-SQL)
適用対象: SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
Microsoft Fabric のSQL 分析エンドポイント
Microsoft Fabric のウェアハウス
Transact-SQL バッチの可能性のある最初の結果セットのメタデータを返します。 バッチが結果を返さない場合は、空の結果セットを返します。 データベース エンジンが静的分析を実行して実行される最初のクエリのメタデータを特定できない場合、エラーが発生します。 動的管理ビュー sys.dm_exec_describe_first_result_set は、同じ情報を返します。
構文
sp_describe_first_result_set [ @tsql = ] N'tsql'
[ , [ @params = ] N'params [ , ...n ]' ]
[ , [ @browse_information_mode = ] <tinyint> ]
[ ; ]
引数
[ @tsql = ] 'tsql'
1 つ以上の Transact-SQL ステートメント。 @tsql は、 nvarchar(n) または nvarchar(max)です。
[ @params = ] N'params'
@params は、transact-SQL バッチのパラメーターの宣言文字列を提供します。これは、 sp_executesql
に似ています。 パラメーターには、 nvarchar(n) または nvarchar(max)があります。
@tsqlに埋め込まれるすべてのパラメーターの定義を含む文字列。 この文字列は Unicode 定数または Unicode 変数にする必要があります。 各パラメーター定義は、パラメーター名とデータ型で構成されます。 n は、追加のパラメーター定義を示すプレースホルダーです。 ステートメントで指定されるすべてのパラメーターは、 @paramsで定義する必要があります。 Transact-SQL ステートメントまたはステートメント内のバッチにパラメーターが含まれていない場合、 @params は必要ありません。 NULL
は、このパラメーターの既定値です。
[ @browse_information_mode = ] tinyint
追加のキー列とソース テーブル情報を返すかどうかを指定します。 1
に設定すると、各クエリはクエリに FOR BROWSE
オプションが含まれているかのように分析されます。
0
に設定すると、情報は返されません。1
に設定すると、各クエリはクエリにFOR BROWSE
オプションが含まれているかのように分析されます。 これにより、ソース列の情報としてベース テーブル名が返されます。2
に設定すると、各クエリは、カーソルの準備または実行で使用されるかのように分析されます。 これにより、ソース列の情報としてビュー名が返されます。
リターン コードの値
sp_describe_first_result_set
成功すると常に 0 の状態が返されます。 プロシージャがエラーをスローし、プロシージャが RPC として呼び出された場合、戻り値の状態は、 sys.dm_exec_describe_first_result_set
のerror_type列で説明されているエラーの種類によって設定されます。 プロシージャが Transact-SQL から呼び出された場合、エラーが発生した場合でも、戻り値は常に 0 になります。
結果セット
この共通メタデータは、結果のメタデータの各列に対する 1 行の結果セットとして返されます。 各行には、列の種類と NULL 値の許容属性が次のセクションに示す形式で記述されます。 すべてのコントロール パスに最初のステートメントが存在しない場合は、行が 0 の結果セットが返されます。
列名 | データ型 | 説明 |
---|---|---|
is_hidden |
bit | 列が情報を参照するために追加された追加の列であり、結果セットに実際には表示されないことを示します。 NULL 値は許可されません。 |
column_ordinal |
int | 結果セット内の列の位置を示す序数を格納します。 最初の列の位置は、 1 として指定されます。 NULL 値は許可されません。 |
name |
sysname | 列の名前を確認できる場合は、その名前を格納します。 それ以外の場合は、NULL になります。 Null 許容。 |
is_nullable |
bit | 列でNULL が許可される場合は1 値を格納し、列でNULL が許可されていない場合は0 し、列でNULL が許可されているかどうかを判断できない場合は1 します。 NULL 値は許可されません。 |
system_type_id |
int | sys.types で指定された列のデータ型のsystem_type_id を格納します。 CLR 型の場合、 system_type_name 列は NULL を返しますが、この列は 240 値を返します。 NULL 値は許可されません。 |
system_type_name |
nvarchar (256) | 列のデータ型に指定されている名前と引数 (長さ、有効桁数、小数点以下桁数など) を格納します。 データ型がユーザー定義の別名型の場合は、基になるシステム型がここで指定されます。 CLR ユーザー定義型の場合は、この列に NULL が返されます。 Null 許容。 |
max_length |
smallint | 列の最大長 (バイト単位) です。-1 = 列データ型が varchar(max)、 nvarchar(max)、 varbinary(max)、または xml です。text列の場合、 max_length 値は16 されるか、sp_tableoption 'text in row' によって設定されます。 NULL 値は許可されません。 |
precision |
tinyint | 数値ベースの場合は、列の有効桁数です。 それ以外の場合は、0 を返します。 NULL 値は許可されません。 |
scale |
tinyint | 数値ベースの場合は、列の小数点以下桁数です。 それ以外の場合は、0 を返します。 NULL 値は許可されません。 |
collation_name |
sysname | 文字ベースの場合は、列の照合順序の名前です。 それ以外の場合は、NULL を返します。 Null 許容。 |
user_type_id |
int | CLR 型とエイリアス型の場合、sys.types で指定された列のデータ型のuser_type_id が含まれます。 それ以外の場合は NULL 。 Null 許容。 |
user_type_database |
sysname | CLR 型と別名型の場合、その型が定義されたデータベースの名前を格納します。 それ以外の場合は NULL 。 Null 許容。 |
user_type_schema |
sysname | CLR 型と別名型の場合、その型が定義されたスキーマの名前を格納します。 それ以外の場合は NULL 。 Null 許容。 |
user_type_name |
sysname | CLR 型と別名型の場合、その型の名前を格納します。 それ以外の場合は NULL 。 Null 許容。 |
assembly_qualified_type_name |
nvarchar (4000) | CLR 型の場合、その型を定義するアセンブリの名前とクラスを返します。 それ以外の場合は NULL 。 Null 許容。 |
xml_collection_id |
int | sys.columns で指定された列のデータ型のxml_collection_id を格納します。 返される型が XML スキーマ コレクションに関連付けられていない場合、この列は NULL を返します。 Null 許容。 |
xml_collection_database |
sysname | この型に関連付けられている XML スキーマ コレクションが定義されているデータベースを格納します。 返される型が XML スキーマ コレクションに関連付けられていない場合、この列は NULL を返します。 Null 許容。 |
xml_collection_schema |
sysname | この型に関連付けられている XML スキーマ コレクションが定義されているスキーマを格納します。 返される型が XML スキーマ コレクションに関連付けられていない場合、この列は NULL を返します。 Null 許容。 |
xml_collection_name |
sysname | この型に関連付けられている XML スキーマ コレクションの名前を格納します。 返される型が XML スキーマ コレクションに関連付けられていない場合、この列は NULL を返します。 Null 許容。 |
is_xml_document |
bit | 返されるデータ型が XML であり、その型が XML フラグメントではなく完全な XML ドキュメント (ルート ノードを含む) であることが保証されている場合は、 1 を返します。 それ以外の場合は、0 を返します。 NULL 値は許可されません。 |
is_case_sensitive |
bit | 列が大文字と小文字を区別する文字列型の場合は 1 を返し、大文字と小文字が区別されない場合は 0 します。 NULL 値は許可されません。 |
is_fixed_length_clr_type |
bit | 列が固定長 CLR 型の場合は 1 を返し、固定長でない場合は 0 します。 NULL 値は許可されません。 |
source_server |
sysname | この結果内の列によって返された元のサーバーの名前です (リモート サーバーから発生する場合)。 名前は、 sys.servers に表示されるとおりに指定されます。 列がローカル サーバーで生成された場合、または列が生成元のサーバーを特定できない場合は、 NULL を返します。 参照情報が要求された場合にのみ設定されます。 Null 許容。 |
source_database |
sysname | この結果内の列によって返された元のデータベースの名前です。 データベースを特定できない場合は、 NULL を返します。 参照情報が要求された場合にのみ設定されます。 Null 許容。 |
source_schema |
sysname | この結果内の列によって返された元のスキーマの名前です。 スキーマを特定できない場合は、 NULL を返します。 参照情報が要求された場合にのみ設定されます。 Null 許容。 |
source_table |
sysname | この結果内の列によって返された元のテーブルの名前です。 テーブルを特定できない場合は、 NULL を返します。 参照情報が要求された場合にのみ設定されます。 Null 許容。 |
source_column |
sysname | 結果列から返された元の列の名前です。 列を特定できない場合は、 NULL を返します。 参照情報が要求された場合にのみ設定されます。 Null 許容。 |
is_identity_column |
bit | 列が ID 列の場合は 1 を返し、そうでない場合は 0 を返します。 列が ID 列であると判断できない場合は、 NULL を返します。 Null 許容。 |
is_part_of_unique_key |
bit | 列が一意のインデックス (一意制約とプライマリ制約を含む) の一部である場合は 1 を返し、含まれていない場合は 0 を返します。 列が一意のインデックスの一部であると判断できない場合は、 NULL を返します。 参照情報が要求された場合にのみ設定されます。 Null 許容。 |
is_updateable |
bit | 列が更新可能な場合は 1 を返し、更新できない場合は 0 します。 列が更新可能であると判断できない場合は、 NULL を返します。 Null 許容。 |
is_computed_column |
bit | 列が計算列の場合は 1 を返し、そうでない場合は 0 します。 列が計算列であると判断できない場合は、 NULL を返します。 Null 許容。 |
is_sparse_column_set |
bit | 列がスパース列の場合は 1 を返し、そうでない場合は 0 します。 列がスパース列セットの一部であると判断できない場合は、 NULL を返します。 Null 許容。 |
ordinal_in_order_by_list |
smallint | リスト内のこの列の位置 ORDER BY 。 列がORDER BY リストに表示されない場合、またはORDER BY リストを一意に決定できない場合は、NULL を返します。 Null 許容。 |
order_by_list_length |
smallint | ORDER BY リストの長さ。 ORDER BY リストがない場合、またはORDER BY リストを一意に決定できない場合は、NULL を返します。 この値は、 sp_describe_first_result_set によって返されるすべての行で同じです。 Null 許容。 |
order_by_is_descending |
smallint | ordinal_in_order_by_list がNULL されていない場合、order_by_is_descending 列は、この列のORDER BY 句の方向を報告します。 それ以外の場合は、 NULL 報告されます。 Null 許容。 |
tds_type_id |
int | 内部使用のみ。 NULL 値は許可されません。 |
tds_length |
int | 内部使用のみ。 NULL 値は許可されません。 |
tds_collation_id |
int | 内部使用のみ。 Null 許容。 |
tds_collation_sort_id |
tinyint | 内部使用のみ。 Null 許容。 |
解説
sp_describe_first_result_set
は、プロシージャが (仮定的な) バッチ A の最初の結果セット メタデータを返し、そのバッチ (A) が実行される場合、バッチは次のいずれかを保証します。
- 最適化時エラーが発生する
- 実行時エラーが発生する
- は結果セットを返しません
- は、次で説明したのと同じメタデータを持つ最初の結果セットを返します
sp_describe_first_result_set
名前、NULL 値の許容属性、およびデータ型が異なる可能性があります。 sp_describe_first_result_set
が空の結果セットを返す場合、バッチ実行は結果セットを返さないことが保証されます。
この保証は、サーバーで関連スキーマが変更されないことを前提としています。 サーバー上の関連するスキーマ変更には、バッチ A に一時テーブルまたはテーブル変数を作成することは含まれません。 sp_describe_first_result_set
が呼び出されてから、バッチ B によって行われたスキーマの変更を含め、実行時に結果セットが返される時間です。
sp_describe_first_result_set
は、次のいずれかの場合にエラーを返します。
入力 @tsql は、有効な Transact-SQL バッチではありません。 有効性は、Transact-SQL バッチの解析と分析によって決定されます。 クエリの最適化中または実行中にバッチによって発生したエラーは、Transact-SQL バッチが有効かどうかを判断する際には考慮されません。
@params は
NULL
ではなく、パラメーターの構文的に有効な宣言文字列ではない文字列を含むか、パラメーターを複数回宣言する文字列が含まれている場合です。入力 Transact-SQL バッチは、 @paramsで宣言されたパラメーターと同じ名前のローカル変数を宣言します。
ステートメントは一時テーブルを使用します。
後でクエリ実行の対象となる永続的なテーブルの作成が、クエリに含まれています。
他のチェックがすべて成功した場合、入力バッチ内で可能性のあるすべての制御フロー パスが考慮されます。 これには、すべての制御フロー ステートメント (GOTO
、 IF
/ELSE
、 WHILE
、および Transact-SQL TRY
/CATCH
ブロック) に加えて、 EXEC
ステートメントによって入力バッチから呼び出されるプロシージャ、動的 Transact-SQL バッチ、またはトリガー、DDL トリガーを発生させる DDL ステートメント、または外部キー制約に対する連鎖アクションのために変更されたターゲット テーブルまたはテーブルでトリガーを発生させる DML ステートメント。 ある時点で、多くの制御パスと同様に、アルゴリズムは停止します。
制御フロー パスごとに、結果セットを返す最初のステートメント (存在する場合) は、 sp_describe_first_result_set
によって決定されます。
バッチで可能性のある最初のステートメントが複数見つかった場合、その結果は、列の数、列の名前、NULL 値の許容、データ型で異なる場合があります。 これらの違いを処理する方法の詳細について、ここに記載します。
列の数が異なる場合は、エラーがスローされ、結果は返されません。
列名が異なる場合、返される列名は
NULL
に設定されます。null 許容が異なる場合、返される null 値の許容によって
NULL
。データ型が異なる場合は、次の場合を除き、エラーがスローされ、結果は返されません。
- varchar(a) から varchar(a') (a' > a)。
- varchar(a) から varchar(max)
- nvarchar(a) から nvarchar(a') (a' > a)。
- nvarchar(a) から nvarchar(max)
- varbinary(a) から varbinary(a') (a' > a)。
- varbinary(a) から varbinary(max)
sp_describe_first_result_set
は間接再帰をサポートしていません。
アクセス許可
@tsql引数を実行するためのアクセス許可が必要です。
例
一般的な例
A. 基本的な例
次の例では、1 つのクエリから返される結果セットについて説明します。
EXEC sp_describe_first_result_set @tsql = N'SELECT object_id, name, type_desc FROM sys.indexes';
次の例では、パラメーターを含む 1 つのクエリから返される結果セットを示します。
EXEC sp_describe_first_result_set @tsql = N'
SELECT object_id, name, type_desc
FROM sys.indexes
WHERE object_id = @id1',
@params = N'@id1 int';
B. 参照モードの例
次の 3 つの例では、異なるブラウズ情報モード間の主要な違いを示します。 クエリ結果には、関連する列のみが含まれます。
0
を使用した例。情報が返されていないことを示します。
CREATE TABLE dbo.t (
a INT PRIMARY KEY,
b1 INT
);
GO
CREATE VIEW dbo.v AS
SELECT b1 AS b2
FROM dbo.t;
GO
EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM dbo.v', NULL, 0;
次に結果セットの一部を示します。
is_hidden | column_ordinal | name | source_schema | source_table | source_column | is_part_of_unique_key |
---|---|---|---|---|---|---|
0 |
1 | b3 | NULL |
NULL |
NULL |
NULL |
クエリに FOR BROWSE オプションが含まれているかのように情報を返すことを示す 1 を使用した例。
EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', NULL, 1;
次に結果セットの一部を示します。
is_hidden | column_ordinal | name | source_schema | source_table | source_column | is_part_of_unique_key |
---|---|---|---|---|---|---|
0 |
1 | b3 | dbo | t | B1 | 0 |
1 |
2 | a | dbo | t | a | 1 |
カーソルを準備しているかのように分析されていることを示す 2 を使用する例。
EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', NULL, 2;
結果セットは次のようになります。
is_hidden | column_ordinal | name | source_schema | source_table | source_column | is_part_of_unique_key |
---|---|---|---|---|---|---|
0 |
1 | B3 | dbo | v | B2 | 0 |
1 |
2 | ROWSTAT | NULL |
NULL |
NULL |
0 |
C: 結果をテーブルに格納する
一部のシナリオでは、スキーマをさらに処理できるように、 sp_describe_first_result_set
プロシージャの結果をテーブルに配置する必要があります。
まず、sp_describe_first_result_set
プロシージャの出力と一致するテーブルを作成する必要があります。
CREATE TABLE #frs (
is_hidden BIT NOT NULL,
column_ordinal INT NOT NULL,
name SYSNAME NULL,
is_nullable BIT NOT NULL,
system_type_id INT NOT NULL,
system_type_name NVARCHAR(256) NULL,
max_length SMALLINT NOT NULL,
precision TINYINT NOT NULL,
scale TINYINT NOT NULL,
collation_name SYSNAME NULL,
user_type_id INT NULL,
user_type_database SYSNAME NULL,
user_type_schema SYSNAME NULL,
user_type_name SYSNAME NULL,
assembly_qualified_type_name NVARCHAR(4000),
xml_collection_id INT NULL,
xml_collection_database SYSNAME NULL,
xml_collection_schema SYSNAME NULL,
xml_collection_name SYSNAME NULL,
is_xml_document BIT NOT NULL,
is_case_sensitive BIT NOT NULL,
is_fixed_length_clr_type BIT NOT NULL,
source_server SYSNAME NULL,
source_database SYSNAME NULL,
source_schema SYSNAME NULL,
source_table SYSNAME NULL,
source_column SYSNAME NULL,
is_identity_column BIT NULL,
is_part_of_unique_key BIT NULL,
is_updateable BIT NULL,
is_computed_column BIT NULL,
is_sparse_column_set BIT NULL,
ordinal_in_order_by_list SMALLINT NULL,
order_by_list_length SMALLINT NULL,
order_by_is_descending SMALLINT NULL,
tds_type_id INT NOT NULL,
tds_length INT NOT NULL,
tds_collation_id INT NULL,
tds_collation_sort_id TINYINT NULL
);
テーブルを作成するとき、そのテーブルにクエリのスキーマを格納できます。
DECLARE @tsql NVARCHAR(MAX) = 'select top 0 * from sys.credentials';
INSERT INTO #frs
EXEC sys.sp_describe_first_result_set @tsql;
SELECT * FROM #frs;
問題の例
以下の例では、すべて 2 つのテーブルを使用します。 次のステートメントを実行して、これらのテーブルを作成します。
CREATE TABLE dbo.t1 (
a INT NULL,
b VARCHAR(10) NULL,
c NVARCHAR(10) NULL
);
CREATE TABLE dbo.t2 (
a SMALLINT NOT NULL,
d VARCHAR(20) NOT NULL,
e INT NOT NULL
);
列の数の違いによるエラー
この例では、可能性のある最初の結果セットの列の数が異なります。
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT a FROM t1;
ELSE
SELECT a, b FROM t1;
SELECT * FROM t; -- Ignored, not a possible first result set.';
データ型の違いによるエラー
考えられる最初の結果セットの間で、列の型が異なります。
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT a FROM t1;
ELSE
SELECT a FROM t2;';
これにより、型の不一致 (int と smallint) のエラーが発生します。
列名を特定できない
可能性のある最初の結果セット内の列で、同じ可変長型の長さ、NULL 値の許容、列の名前が異なります。
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT b FROM t1;
ELSE
SELECT d FROM t2;';
次に結果セットの一部を示します。
列 | Value |
---|---|
name |
不明な列名 |
system_type_name |
varchar |
max_length |
20 |
is_nullable |
1 |
別名を使用して列の名前を強制的に同一にする
前の例と同じですが、列の別名を使用して列名を同じにしています。
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT b FROM t1;
ELSE
SELECT d AS b FROM t2;';
次に結果セットの一部を示します。
列 | Value |
---|---|
name |
b |
system_type_name |
varchar |
max_length |
20 |
is_nullable |
1 |
列の型が一致できないためにエラーが発生しました
可能性のある複数の最初の結果セットの間で、列の型が異なります。
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT b FROM t1;
ELSE
SELECT c FROM t1;';
これにより、型の不一致 (varchar(10) と nvarchar(10)) のエラーが発生します。
結果セットがエラーを返す可能性がある
最初の結果セットはエラーまたは結果セットです。
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
RAISERROR(''Some Error'', 16 , 1);
ELSE
SELECT a FROM t1;
SELECT e FROM t2; -- Ignored, not a possible first result set.';
次に結果セットの一部を示します。
列 | Value |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
一部のコード パスが結果を返さない
最初の結果セットが null または結果セットです。
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
RETURN;
SELECT a FROM t1;';
次に結果セットの一部を示します。
列 | Value |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
動的 SQL からの結果
最初の結果セットは、リテラル文字列であるために検出可能な動的 SQL です。
EXEC sp_describe_first_result_set @tsql = N'
EXEC(N''SELECT a FROM t1'');';
次に結果セットの一部を示します。
列 | Value |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
動的 SQL からの結果の失敗
動的 SQL のため、最初の結果セットが未定義となります。
EXEC sp_describe_first_result_set @tsql = N'
DECLARE @SQL NVARCHAR(max);
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1'';
IF (1 = 1)
SET @SQL += N'' AND e > 10'';
EXEC(@SQL);';
これにより、エラーが発生します。 動的 SQL のため、結果を検出できません。
ユーザー指定の結果セット
最初の結果セットがユーザーにより手動で指定されています。
EXEC sp_describe_first_result_set @tsql =
N'
DECLARE @SQL NVARCHAR(max);
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1'';
IF (1 = 1)
SET @SQL += N'' AND e > 10'';
EXEC(@SQL)
WITH RESULT SETS (
(Column1 BIGINT NOT NULL)
);';
次に結果セットの一部を示します。
列 | Value |
---|---|
name |
Column1 |
system_type_name |
bigint |
is_nullable |
0 |
あいまいな結果セットによって発生するエラー
この例では、user1
という名前の別のユーザーが、既定のスキーマ s1
に列 (a int NOT NULL
) t1
という名前のテーブルを持っていることを前提としています。
EXEC sp_describe_first_result_set @tsql = N'
IF (@p > 0)
EXECUTE AS USER = ''user1'';
SELECT * FROM t1;',
@params = N'@p int';
このコードにより、 Invalid object name
エラーが発生します。 t1
は、それぞれ異なる数の列を持つ dbo.t1
または s1.t1
にすることができます。
結果セットがあいまいな場合でも得られる結果
前の例と同じ想定を使います。
EXEC sp_describe_first_result_set @tsql =
N'
IF (@p > 0)
EXECUTE AS USER = ''user1'';
SELECT a FROM t1;';
次に結果セットの一部を示します。
列 | Value |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
dbo.t1.a
とs1.t1.a
の両方に、int型と異なる null 許容があります。