[以前この質問に回答したことがあることに気づきました]
ストアド プロシージャに対してこれを行うのは、ビューやテーブルの場合よりもはるかに複雑です。問題の 1 つは、ストアド プロシージャが、入力パラメーターや、サーバーの状態や時刻などのように制御できないものに応じて、複数の異なるコード パスを持つ可能性があることです。このストアドプロシージャ?条件に関係なく複数の結果セットがある場合はどうなりますか?
CREATE PROCEDURE dbo.foo
@bar INT
AS
BEGIN
SET NOCOUNT ON;
IF @bar = 1
SELECT a, b, c FROM dbo.blat;
ELSE
SELECT d, e, f, g, h FROM dbo.splunge;
END
GO
ストアド プロシージャにコード パスがなく、常に同じ結果セットが表示されると確信している (また、ストアド プロシージャにオプションではないパラメーターがある場合にどの値を指定する必要があるかを事前に判断できる) 場合は、簡単な例を見てみましょう。
CREATE PROCEDURE dbo.bar
AS
BEGIN
SET NOCOUNT ON;
SELECT a = 'a', b = 1, c = GETDATE();
END
GO
FMTONLY
1 つの方法は、次のようにすることです。
SET FMTONLY ON;
GO
EXEC dbo.bar;
これにより、空の結果セットが得られ、クライアント アプリケーションはその結果セットのプロパティを調べて、列名とデータ型を判断できます。
ここではSET FMTONLY ON;
説明しませんが、少なくとも、このコマンドは非推奨であることに注意してください。これには正当な理由があります。また、完了したときにも注意してSET FMTONLY OFF;
ください。そうしないと、ストアド プロシージャを正常に作成したのに実行できないのはなぜだろうと思うでしょう。いいえ、それについて警告しているわけではありません。本音。:-)
OPENQUERY
ループバック リンク サーバーを作成すると、ストアド プロシージャの実行などのツールを使用OPENQUERY
して、検査可能な構成可能な結果セットを返すことができます (非常に大まかな定義として受け入れてください)。最初にループバック サーバーを作成します (これは という名前のローカル インスタンスを想定していますFOO
)。
USE master;
GO
EXEC sp_addlinkedserver @server = N'.\FOO', @srvproduct=N'SQL Server'
GO
EXEC sp_serveroption @server=N'.\FOO', @optname=N'data access',
@optvalue=N'true';
上記の手順を実行して、次のようなクエリにフィードできます。
SELECT * INTO #t
FROM OPENQUERY([.\FOO], 'EXEC dbname.dbo.bar;')
WHERE 1 = 0;
SELECT c.name, t.name
FROM tempdb.sys.columns AS c
INNER JOIN sys.types AS t
ON c.system_type_id = t.system_type_id
WHERE c.[object_id] = OBJECT_ID('tempdb..#t');
これはエイリアス タイプ (以前はユーザー定義データ タイプと呼ばれていました) を無視し、たとえばsysname
. しかし、上記から次のようになります。
name name
---- --------
b int
c datetime
a varchar
明らかに、ここで行う作業は他にもあります。長さは表示されません。また、やvarchar
などの他の型の精度/スケールを取得する必要があります。しかし、それは始まりです。datetime2
time
decimal
SQL Server 2012
SQL Server 2012 には、メタデータの検出をより簡単にするいくつかの新機能があります。上記の手順では、次のことができます。
SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set_for_object
(
OBJECT_ID('dbo.bar'),
NULL
);
とりわけ、これは実際に精度とスケールを提供し、エイリアス タイプを解決します。上記の手順では、次の結果が得られます。
name system_type_name
---- ----------------
a varchar(1)
b int
c datetime
視覚的には大きな違いはありませんが、さまざまな精度とスケールを持つすべての異なるデータ型を使い始めると、この関数が行う余分な作業に感謝するでしょう。
欠点: SQL Server 2012 では、少なくともこれらの関数は最初の結果セットに対してのみ機能します(関数の名前が示すように)。