sp_describe_first_result_set (Transact-SQL)

 

THIS TOPIC APPLIES TO:yesSQL Server (starting with 2012)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

Transact-SQL バッチの考えられる最初の結果セットのメタデータを返します。 バッチから結果が返されない場合は、空の結果セットを返します。 静的分析の実行によって実行される最初のクエリのメタデータをデータベース エンジンが特定できない場合は、エラーが発生します。 動的管理ビュー sys.dm_exec_describe_first_result_set (Transact-SQL) は同じ情報を返します。

Topic link icon Transact-SQL 構文表記規則

適用対象:SQL Server (SQL Server 2012 から現在のバージョン)、Azure SQL データベース。
  
sp_describe_first_result_set [ @tsql = ] N'Transact-SQL_batch'   
    [ , [ @params = ] N'parameters' ]   
    [ , [ @browse_information_mode = ] <tinyint> ] ]  

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

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

Transact-SQL _batch に埋め込まれたすべてのパラメーターの定義が含まれている 1 つの文字列を指定します。 この文字列は 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_hiddenbit NOT NULLこの列が、参照情報のために追加された余分な列で、実際に結果セットには表示されないかどうかを示します。
column_ordinalint NOT NULL結果セット内の列の位置を示す序数を格納します。 最初の列の位置は 1 で指定されます。
namesysname NULL列の名前を確認できる場合は、その名前を格納します。 それ以外の場合、NULL が格納されます。
is_nullablebit NOT NULL列が NULL を許可する場合は 1、NULL を許可しない場合は 0、NULL を許可するかどうかを特定できない場合は 1 を格納します。
system_type_idint NOT NULLsys.types
で指定された列のデータ型の system_type_id を格納します。 CLR 型の場合は、system_type_name 列が NULL を返しても、この列は値 240 を返します。
system_type_namenvarchar(256) NULL列のデータ型に指定されている名前と引数 (長さ、有効桁数、小数点以下桁数など) を格納します。 データ型がユーザー定義の別名型の場合は、基になるシステム型がここで指定されます。 CLR ユーザー定義型の場合は、この列には NULL が返されます。
max_lengthsmallint NOT NULL列の最大長 (バイト単位) です。

-1 の場合、列のデータ型は varchar(max)nvarchar(max)varbinary(max)、または xml です。

 text 列の場合、max_length の値は 16 か、sp_tableoption 'text in row' によって設定された値になります。
有効桁数 (precision)tinyint NOT NULL数値ベースの場合は、列の有効桁数です。 それ以外の場合は 0 を返します。
scaletinyint NOT NULL数値ベースの場合は、列の小数点以下桁数です。 それ以外の場合は 0 を返します。
collation_namesysname NULL文字ベースの場合は、列の照合順序の名前です。 それ以外の場合は NULL を返します。
user_type_idint NULLCLR 型と別名型の場合、sys.types で指定された列のデータ型の user_type_id を格納します。 それ以外の場合は NULL です。
user_type_databasesysname NULLCLR 型と別名型の場合、その型が定義されたデータベースの名前を格納します。 それ以外の場合は NULL です。
user_type_schemasysname NULLCLR 型と別名型の場合、その型が定義されたスキーマの名前を格納します。 それ以外の場合は NULL です。
user_type_namesysname NULLCLR 型と別名型の場合、その型の名前を格納します。 それ以外の場合は NULL です。
assembly_qualified_type_namenvarchar(4000)CLR 型の場合、その型を定義するアセンブリの名前とクラスを返します。 それ以外の場合は NULL です。
xml_collection_idint NULLsys.columns
で指定された列のデータ型の xml_collection_id を格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。
xml_collection_databasesysname NULLこの型に関連付けられている XML スキーマ コレクションが定義されているデータベースを格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。
xml_collection_schemasysname NULLこの型に関連付けられている XML スキーマ コレクションが定義されているスキーマを格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。
xml_collection_namesysname NULLこの型に関連付けられている XML スキーマ コレクションの名前を格納します。 この列は、返される型が XML スキーマ コレクションに関連付けられていない場合は NULL を返します。
is_xml_documentbit NOT NULL返されたデータ型が XML で、その型が XML フラグメントではなく完全な XML ドキュメント (ルート ノードを含む) であると保証される場合、1 を返します。 それ以外の場合は 0 を返します。
is_case_sensitivebit NOT NULLこの列が大文字と小文字を区別する文字列型の場合は 1、それ以外の場合は 0 を返します。
is_fixed_length_clr_typebit NOT NULLこの列が固定長の CLR 型の場合は 1、それ以外の場合は 0 を返します。
source_serversysnameこの結果内の列によって返された元のサーバーの名前です (リモート サーバーから発生する場合)。 これは、sys.servers に表示される名前です。 この列がローカル サーバー上で発生した場合、または元のサーバーを特定できない場合は NULL を返します。 参照情報が要求された場合にのみ設定されます。
source_databasesysnameこの結果内の列によって返された元のデータベースの名前です。 データベースを特定できない場合は NULL を返します。 参照情報が要求された場合にのみ設定されます。
source_schemasysnameこの結果内の列によって返された元のスキーマの名前です。 スキーマを特定できない場合は NULL を返します。 参照情報が要求された場合にのみ設定されます。
source_tablesysnameこの結果内の列によって返された元のテーブルの名前です。 テーブルを特定できない場合は NULL を返します。 参照情報が要求された場合にのみ設定されます。
source_columnsysname結果列から返された元の列の名前です。 列を特定できない場合は NULL を返します。 参照情報が要求された場合にのみ設定されます。
is_identity_columnbit NULLこの列が ID 列の場合は 1、それ以外の場合は 0 を返します。 ID 列であることを確認できない場合は NULL を返します。
is_part_of_unique_keybit NULLこの列が一意インデックス (一意制約と主キー制約を含む) の一部である場合は 1、それ以外の場合は 0 を返します。 一意インデックスの一部であることを確認できない場合は NULL を返します。 参照情報が要求された場合にのみ設定されます。
is_updateablebit NULLこの列が更新可能である場合は 1、それ以外の場合は 0 を返します。 更新可能であることを確認できない場合は NULL を返します。
is_computed_columnbit NULLこの列が計算列の場合は 1、それ以外の場合は 0 を返します。 計算列であることを確認できない場合は NULL を返します。
is_sparse_column_setbit NULLこの列がスパース列の場合は 1、それ以外の場合は 0 を返します。 スパース列セットの一部であることを確認できない場合は NULL を返します。
ordinal_in_order_by_listsmallint NULLORDER BY リストにおけるこの列の位置を返します。 この列が ORDER BY リストにない場合、または ORDER BY リストを一意に特定できない場合は NULL を返します。
order_by_list_lengthsmallint NULLORDER BY リストの長さを返します。 ORDER BY リストがない場合、または ORDER BY リストを一意に特定できない場合は NULL を返します。 この値は、sp_describe_first_result_set によって返されるすべての行に対して同じであることに注意してください。
order_by_is_descendingsmallint NULLordinal_in_order_by_list が NULL でない場合、order_by_is_descending 列には、この列の ORDER BY 句の方向が報告されます。 それ以外の場合は、NULL が報告されます。
tds_type_idint NOT NULL内部使用です。
tds_lengthint NOT NULL内部使用です。
tds_collation_idint NULL内部使用です。
tds_collation_sort_idtinyint NULL内部使用です。

sp_describe_first_result_set は、プロシージャが (仮定の) バッチ A の最初の結果セットのメタデータを返し、かつそのバッチ (A) が続けて実行される場合に、そのバッチで (1) 最適化時エラーが発生する、(2) 実行時エラーが発生する、(3) 結果セットが返されない、または (4) sp_describe_first_result_set で記述されるのと同じメタデータと共に最初の結果セットが返される、のいずれかであることを保証します。

名前、NULL 値の許容属性、およびデータ型が異なる可能性があります。 sp_describe_first_result_set が空の結果セットを返す場合は、バッチの実行によって結果セットが返されないことが保証されます。

この保証は、サーバー上で関連スキーマの変更がないことを前提としています。 サーバー上での関連スキーマの変更には、sp_describe_first_result_set が呼び出されてから実行中に結果セットが返されるまでの間のバッチ A での一時テーブルやテーブル変数の作成 (バッチ 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 ブロック)、任意のプロシージャ、動的 Transact-SQL バッチ、または、EXEC ステートメント、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 つのクエリから返される結果セットを示します。

sp_describe_first_result_set @tsql = N'SELECT object_id, name, type_desc FROM sys.indexes'  

次の例は、パラメーターを含む 1 つのクエリから返される結果セットを示します。

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_hiddencolumn_ordinalnamesource_schemasource_tablesource_columnis_part_of_unique_key
01b3NULLNULLNULLNULL

1 を使用した例は、クエリに FOR BROWSE オプションが含まれているかのように情報が返されることを示します。

EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', null, 1  
  

以下に結果セットを示します。

is_hiddencolumn_ordinalnamesource_schemasource_tablesource_columnis_part_of_unique_key
01b3dbotB10
12adbota1

2 を使用した例は、カーソルを準備しているかのように分析されることを示します。

EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', null, 2  

以下に結果セットを示します。

is_hiddencolumn_ordinalnamesource_schemasource_tablesource_columnis_part_of_unique_key
01B3dbovB20
12ROWSTATNULLNULLNULL0

問題の例

以下の例では、すべて 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);  

列の数の違いによるエラー

この例では、考えられる最初の結果セットの間で、列の数が異なります。

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

データ型の違いによるエラー

考えられる最初の結果セットの間で、列の型が異なります。

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

結果:エラー、型の不一致 (intsmallint)。

列名の特定不可

考えられる最初の結果セットの間で、列の同じ可変長型の長さ、NULL 値の許容属性、列名が異なります。

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

結果:<不明な列名> varchar(20) NULL

別名を使用して強制的に列名を同じにする

前の例と同じですが、列の別名を使用して列名を同じにしています。

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

結果:b varchar(20)NULL

列の型の不一致によるエラー

考えられる、異なる最初の結果セットの間で、列の型が異なります。

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

結果:エラー、型の不一致 (varchar(10)nvarchar(10)).

結果セットがエラーを返す

最初の結果セットがエラーまたは結果セットです。

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

結果:a intNULL

いくつかのコード パスが結果を返さない

最初の結果セットが null または結果セットです。

sp_describe_first_result_set @tsql =   
N'  
IF(1=1)  
    RETURN;  
SELECT a FROM t1;'  

結果:a intNULL

動的 SQL からの結果

最初の結果セットが、リテラル文字列であるため検出可能な動的 SQL です。

sp_describe_first_result_set @tsql =   
N'EXEC(N''SELECT a FROM t1'');'  

結果:a INT NULL

動的 SQL からの結果の失敗

動的 SQL のため、最初の結果セットが未定義となります。

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 のため、結果を検出できません。

ユーザー指定の結果セット

最初の結果セットがユーザーにより手動で指定されています。

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

結果:Column1 bigint NOT NULL

あいまいな結果セットによるエラー

次の例では、user1 という名前の別のユーザーが、既定のスキーマ s1 内に列 (int NOT NULL) を持つテーブル t1 を持っていることを前提としています。

sp_describe_first_result_set @tsql =   
N'  
    IF(@p > 0)  
    EXECUTE AS USER = ''user1'';  
    SELECT * FROM t1;'  
, @params = N'@p int'  

結果:エラー状態。 t1 は dbo.t1 または s1.t1 のいずれかで、それぞれ列の数が異なる可能性があります。

あいまいな結果セットによる結果

前の例と同じ前提を使用します。

sp_describe_first_result_set @tsql =   
N'  
    IF(@p > 0)  
    EXECUTE AS USER = ''user1'';  
    SELECT a FROM t1;'  

結果:a int NULL dbo.t1.a と s1.t1.a がどちらもデータ型 int で、NULL 値の許容属性が異なるため。

sp_describe_undeclared_parameters (Transact-SQL)
sys.dm_exec_describe_first_result_set (Transact-SQL)
sys.dm_exec_describe_first_result_set_for_object (Transact-SQL)

コミュニティの追加

表示: