出力パラメーターを使用してストアード・プロシージャーを作成する方法を知っています。しかし、単純なSELECT
ステートメントを使用するだけでそれを使用する理由がわかりません。通常のストアドプロシージャは、グリッドで出力を返すことができます(以下の例を参照)。
SP出力パラメータなしでSP出力パラメータなしで使用できる実際の例を誰かに教えてもらえますか?
-- Using output parameter
SELECT @var = COUNT(*) FROM table1 WHERE gender = @gender...
-- Without output parameter
SELECT COUNT(*) FROM table WHERE gender = @gender...
ストアドプロシージャの出力パラメーターは、呼び出し元のT-SQLに値を返すのに役立ちます。呼び出し元のT-SQLは、その値を他のものに使用できます。
都市の入力を与えられた州を出力パラメーターとするストアドプロシージャがあるとします。
CREATE PROCEDURE [dbo].[GetStateFromCity] (@City NVARCHAR(30), @State NCHAR(2) OUTPUT)
AS
SELECT @State = [State]
FROM [ExampleTable]
WHERE [City] = @City
GO;
この出力パラメーターを使用して、他の場所に値を渡すことができます。
例えば:
DECLARE @State int
EXEC [dbo].[GetStateFromCity] @City = 'Calgary', @State OUTPUT;
-- Do something with this value
SELECT @State;
-- Do something else
EXEC [dbo].[GetInsuranceCompanyByState] @State;
要約すると、クライアントアプリケーションの値を返すだけの場合は、おそらく出力パラメーターは必要ありません。
ただし、ストアドプロシージャ間でT-SQLの値を渡したい場合は、非常に便利です。
それだけの価値があるので、私は出力パラメーターをほとんど使用しません。
この質問がSQL Serverに関連すると仮定すると、それはコンテキストと効率に帰着します。
コンテキスト=アプリコード
アプリのコードからストアドプロシージャを実行する場合、コードの量はそれほど変わりません。結果セットを返すときは、ExecuteReader
を呼び出し、次にSqlDataReader.Read()
を呼び出して1つの行を取得し、次にSqlDataReader
から列を取得します。ただし、単一の値を取得しているだけの場合は、ExecuteScalar
のショートカットメソッドを使用して、行が1つでも(行がまだある場合でも)取得し、最初の列に値を返します(行がある場合でも)より多くの列です)。 OUTPUT
パラメータを返すときは、ExecuteNonQuery
を呼び出して、各パラメータの.Value
プロパティを確認し、適切な型にキャストするだけです。
したがって、単一の値を返す単純な例の観点から見ると、結果セットを返し、ExecuteScalar
を呼び出すのが「最も簡単」のようです。しかし、ExecuteReader
またはExecuteScalar
を使用しているかどうかにかかわらず、結果セットを返すには、SQL Serverとクライアントアプリの両方のリソースがさらに必要です。 SQL Serverは結果セットをセットアップして管理する必要があります(つまり、メモリと時間を必要とします)。アプリはSqlDataReader
をインスタンス化し(ExecuteScalar
を使用している場合でも)、それを管理する必要があります(つまりメモリと時間が必要です)。結果セットの行が1つしかないことが保証されている場合は、出力パラメーターを使用することをお勧めします(わずかであっても)。
コンテキスト= T-SQL
T-SQLからストアドプロシージャを実行する場合(および戻り値を使用する必要がある場合)、OUTPUT
パラメータを使用する方が便利です。結果セットを返すことは使用可能ですが、INSERT ... EXEC
を使用して、結果をテーブル(通常はローカル一時テーブルまたはテーブル変数)に挿入する必要があります。ただし、その場合も行を選択してローカル変数に入れる必要があります。繰り返しになりますが、変数に値を配置する同じ場所にたどり着くには、より多くの時間とリソースが必要です。
これで、単一の値のみを返す場合(つまり、ExecuteScalar
で機能する同じ状況)、timesを使用してスカラーを使用できます代わりにユーザー定義関数(UDF)。これは、クエリに配置できるため、(クエリでスカラーUDFを使用することでパフォーマンスが低下した場合でも)非常に便利です。ただし、UDFで実行できることには多くの制限があるため、一時テーブルを作成したり、DMLやDDLなどを実行したりする必要がある場合は、ストアドプロシージャを使用するしか選択肢がありません。
「結果セットとOUTPUTパラメータ」の質問の一部ではありませんが、あなたが両方できることを覚えておいてください。控えめな値と返すデータのセットがある場合、ストアドプロシージャは両方を返すことを許可しますが、まれに非常に役立ちます。
注目に値する他の2つのこと:
1)OUTPUT
として複数のパラメーターを渡すことができます。
2)結果が必要ない場合は、OUTPUT
を使用してパラメーターを呼び出す必要はありません。
CREATE PROCEDURE ManyOutputs @a int, @b int output, @c varchar(100) output, @d bit output
AS
BEGIN
SET @b = @a + 11
SET @c = 'The Value of A is ' + CAST(@a AS varchar(5)) + ', and the value of B is ' + CAST(@b AS varchar(5))
IF (@a % 2 = 1)
SET @d = 1
ELSE
SET @d = 0
END
GO
このルーチンを呼び出す:
DECLARE @bVal int
DECLARE @cVal varchar(100)
DECLARE @dVal bit
EXEC ManyOutputs 1, @bVal, @cVal, @dVal
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal
NULL、NULL、NULLを返します
EXEC ManyOutputs 2, @bVal OUT, @cVal OUT, @dVal OUT
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal
13、「Aの値は2、Bの値は13」、0を返します
EXEC ManyOutputs 3, @bVal, @cVal, @dVal
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal
13、「Aの値は2、Bの値は13」、0を返します
(前回の呼び出しと同じです。OUTPUT
を使用して新しい値を取得しなかったため、古い値が保持されていました。)
EXEC ManyOutputs 5, @bVal OUT, @cVal OUT, @dVal OUT
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal
16、「Aの値は5、Bの値は16」、1を返します