次の方法で共有


sp_describe_first_result_set (Transact-SQL)

Applies to: 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 は、同じ情報を返します。

Transact-SQL 構文表記規則

構文

sp_describe_first_result_set [ @tsql = ] N'tsql'
    [ , [ @params = ] N'@parameter_name data_type [ , ... n ]' ]
    [ , [ @browse_information_mode = ] <tinyint> ]
[ ; ]

引数

[ @tsql = ] 'tsql'

1 つ以上の Transact-SQL ステートメント。 @tsql は、 nvarchar(n) または nvarchar(max)です。

[ @params = ] N'@parameter_name data_type [ , ... n ]'

@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_listNULLされていない場合、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 バッチが有効かどうかを判断する際には考慮されません。

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

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

  • ステートメントは一時テーブルを使用します。

  • 後でクエリ実行の対象となる永続的なテーブルの作成が、クエリに含まれています。

他のチェックがすべて成功した場合、入力バッチ内で可能性のあるすべての制御フロー パスが考慮されます。 これには、すべての制御フロー ステートメント (GOTOIF/ELSEWHILE、および 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;';

これにより、型の不一致 (intsmallint) のエラーが発生します。

列名を特定できない

可能性のある最初の結果セット内の列で、同じ可変長型の長さ、NULL 値の許容、列の名前が異なります。

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    SELECT b FROM t1;
ELSE
    SELECT d FROM t2;';

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

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;';

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

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.';

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

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;';

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

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'');';

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

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)
    );';

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

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;';

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

name a
system_type_name int
is_nullable 1

dbo.t1.as1.t1.aの両方に、int型と異なる null 許容があります。