SQL Server 2008 Enterpriseを使用しています。 SQL ServerストアドプロシージャのOUTPUTパラメーターを学習しています。たとえば、ストアドプロシージャsp_add_jobscheduleには、schedule_idというOUTPUTパラメーターがあります。
http://msdn.Microsoft.com/en-us/library/ms366342.aspx
私の混乱は、OUTPUTパラメーターに入力値を提供し、値を返すように見えることです。INPUTパラメーターとOUTPUTパラメーターの両方の動作があるように見えますか? (純粋な出力パラメーターの動作のように見せるために)OUTPUTパラメーターにINPUT値を提供しないことは許可されていますか?
混乱はある程度正当化されます-Oracleなどの他のRDBMSには、IN
(入力のみ)、OUT
(出力のみ)、またはINOUT
(両方の方法-「参照渡し」タイプのパラメーター)。
SQL ServerはパラメーターをOUTPUT
とラベル付けするため、ここでは少しずさんですが、実際には、これはINPUT
/OUTPUT
を意味します-基本的には、ストアドプロシージャにチャンスがあることを意味しますそのパラメータでの呼び出しから値を返す。
はい-OUTPUT
パラメーターと呼ばれていますが、実際にはINPUT
/OUTPUT
パラメーターと、それらのIN
、INOUT
、OracleのようなOUT
は、SQL Server(T-SQL)には存在しません。
出力パラメーターを使用してストアドプロシージャを作成する方法の簡単な例を示します。
CREATE PROCEDURE test_proc
@intInput int,
@intOutput int OUTPUT
AS
set @intOutput = @intInput + 1
go
このプロシージャを呼び出して出力パラメータを使用するには、次のようにします。
declare @intResult int
exec test_proc 3 ,@intResult OUT
select @intResult
Ouput変数を最初に宣言する必要があることがわかります。ストアドプロシージャを実行すると、出力値が変数に格納されます。出力変数には任意の値を設定できますが、ストアドプロシージャを実行すると、出力変数にどの値が含まれていても、返されるストアドプロシージャが正確に含まれます。
例えば:
declare @intResult int
exec test_proc 3 ,@intResult OUT
select @intResult
4を返します。
declare @intResult int
set @intResult = 8
exec test_proc 3 ,@intResult OUT
select @intResult
4も返します。
はい、値の受け渡しと取得の両方にOUTPUTパラメーターを使用できます(現時点では、それを行う正当な理由は考えられませんが)。
これを示す簡単な例を次に示します。
-- The stored procedure
CREATE PROCEDURE OutParamExample
@pNum int OUTPUT
AS
BEGIN
select @pNum
set @pNum = @pNum + 5
END
GO
-- use a local variable to retrieve your output param value
declare @TheNumber int
set @TheNumber = 10
print @TheNumber
exec OutParamExample @TheNumber OUTPUT
print @TheNumber
結果は次のようになります。
10
-----------
10
(1 row(s) affected)
15
編集: OK、2番目の段落で「not」を逃し、あなたが尋ねた質問に答えていない可能性があると思います。厳密な出力パラメーター(戻りコードなど)が必要な場合、次のように渡されるローカル変数にvalueを指定する必要はありません。出力パラメータですが、プロシージャ自体のスコープ外で返された値にアクセスできるように、ローカル変数を宣言する必要があります。
例えば:
declare @LocalNumber int
-- I don't have to assign a value to @LocalNumber to pass it as a parameter
exex OutParamExample @LocalNumber OUTPUT
-- (assume SP has been altered to assign some reasonable value)
-- but I do have to declare it as a local variable so I can get to
-- the return value after the stored procedure has been called
print @LocalNumber
上記で他の人が言ったことにさらに加えて、OUTPUTパラメーターはINPUTとOUTPUTとして機能できます。ただし、渡された値を使用するのはストアドプロシージャに依存します。
ストアドプロシージャがOUTPUTパラメータに渡された値を無視する場合(通常はそうする必要があります)、とにかくINPUT値は無視されます。
Sergeyのコードを使用して、@ intOutputに渡されたユーザー値を使用できます(必要な場合)
create PROCEDURE test_proc
@intInput int,
@intOutput int OUTPUT
AS
set @intOutput = @intOutput + 1
go
しかし、それはOUTPUTパラメーターの目的に反します。
別のビューを表示するために、c#コンパイラーは、出力パラメーターを使用せずに、割り当てによってoutパラメーターの値を強制的に上書きします。
例えば私はC#でこれを行うことはできません。ここでは、出力パラメーターとしてのみ機能します(つまり、ユーザーがこの関数に渡した値を無視します)
static void dosomething(out int i)
{
//i = 0;
i = i + 1;
}
質問は-理由入力の提供を禁止しますか?これはまったく意味がありません。この簡単な例を考えてみましょう。
CREATE PROCEDURE test (@param AS INT OUTPUT) AS
BEGIN
SET @param = 100
END
GO
DECLARE @i INT
SET @i = 0
EXECUTE test @i OUTPUT
PRINT @i
DROP PROCEDURE test
これは印刷します
100
参照-変数を最初に入れない場合out値を取得する方法in最初に?
プログラミング言語の参照によって渡される出力パラメーターについて考えてみましょう、それは同じです。私が今考えることができる最良の例は、エラーコードを返すことです。いくつかの挿入が必要です... SPからリターンコードを選択した場合、それをコード内にフェッチする必要があります。OUTPUTパラメータを持たない場合は、すでにパラメータ内にあります(つまり、 C#コマンド、PHP init stored procメソッド、または文字列を作成する場合とは異なる何か)
元の質問の一部に関する追加の注記:
「OUTPUTパラメーター(..)にINPUT値を提供しないことは許可されていますか?」
SQLServerでは、OUTPUTパラメータのデフォルト値を指定することができます(他の人が実際にINOUTを指摘したように)。明示的な値を指定したり、関数自体にIDを生成させたりできる次の例を考えてください。
CREATE PROCEDURE test (@id uniqueidentifier = NULL OUTPUT) AS
BEGIN
IF @id IS NULL SET @id = NEWID()
-- INSERT INTO xyz (...) VALUES (@id, ...)
PRINT 'Insert with id: ' + CAST (@id as nvarchar(36))
END
GO
DECLARE @insertedId uniqueidentifier
EXECUTE test '00000000-0000-0000-0000-000000000000'
EXECUTE test @insertedId OUTPUT
PRINT @insertedId
DROP PROCEDURE test
これは印刷します
Insert with id: 00000000-0000-0000-0000-000000000000
Insert with id: 67AE3D27-8EAB-4301-B384-30EEA1488440
67AE3D27-8EAB-4301-B384-30EEA1488440
注目に値する他の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を返します