2009-04-14 23 views
32

おそらく簡単な質問です。私は、この手順を持っている:ストアドプロシージャの戻り値を取得する方法

CREATE PROCEDURE [dbo].[AccountExists] 
    @UserName nvarchar(16) 
AS 
IF EXISTS (SELECT Id FROM Account WHERE [email protected]) 
SELECT 1 
ELSE SELECT 0 

私は、このプロシージャを呼び出すと、この行いADO.NETコードがある場合:

return Convert.ToBoolean(sproc.ExecuteScalar()); 

真か偽のどちらかが返されます。

Iの代わりにSELECTの1又は0を返すために、ストアドプロシージャを変更:

ALTER PROCEDURE [dbo].[AccountExists] 
    @UserName nvarchar(16) 
AS 
IF EXISTS (SELECT Id FROM Account WHERE [email protected]) 
RETURN 1 
ELSE RETURN 0 

sproc.ExecuteScalar()はnullを返します。代わりにsproc.ExecuteNonQuery()を試行すると、-1が返されます。

ADO.NETでRETURNを使用してストアドプロシージャの結果を取得するにはどうすればよいですか?私はAccountExistsは、SELECTの代わりに返す必要が

ので、私は別のストアドプロシージャを持つことができ、それを呼び出す:

--another procedure to insert or update account 

DECLARE @exists bit 

EXEC @exists = [dbo].[AccountExists] @UserName 

IF @exists=1 
--update account 
ELSE 
--insert acocunt 
+0

@Chris:被写体はより具体的に編集する必要があります。件名からは、T-SQLとADO.NETとは何の関係もありません。 –

+0

笑、それは意図的ではなかった。私が注目しているのは、私がその主題をタイプしているからです。 – core

答えて

40

ParameterDirection.ReturnValueを使用して、パラメータを追加します。戻り値は、実行後にパラメータに表示されます。

+3

ReturnValueが最初のパラメータでなければならないことが分かるまで、これはVBAで私にとってはうまくいきませんでした。 http://stackoverflow.com/a/25528645/2559297 –

+0

「コマンドにパラメータを追加する」ストアドプロシージャに? – TylerH

0

次の例のように使用したい場合は、AccountExistsを関数として使用する方がよいでしょう。

それ以外の場合は、ストアドプロシージャの結果を別のストアドプロシージャから呼び出すことで、その結果を選択することができます。

3

ExecuteScalarは、最初の行の最初の列を返します。あなたはもはや選択をしていないし、結果セットを作成しているので、それはnullを返す理由です。 FYIと同じように。ジョン・サンダースは正解です。

1

デフォルトでは、何か他のことを指定しない限り、ストアドプロシージャは0を返します。このため、成功を示すために0が使用され、戻りエラー条件を指定するには0以外の値が使用されます。 John's suggestionとするか、output parameter

9

を使用してください。また、ADO.NETから結果(またはその他の出力パラメータ)を取得するには、返されたすべての結果セットをループバックする必要があります(またはNextResult )

つまり、あなたは次のように定義された手順がある場合:

CREATE PROC Test(@x INT OUT) AS 
    SELECT * From TestTable 
    SELECT @x = 1 

をそして、これを行うにしてみてください。

SqlCommand cmd = connection.CreateCommand(); 
cmd.CommandType = CommandType.StoredProcedure; 
cmd.CommandText = "Test" 
cmd.Parameters.Add("@x", SqlDbType.Int).Direction = ParameterDirection.Output; 
cmd.Parameters.Add("@retval", SqlDbType.Int).Direction = ParameterDirection.ReturnValue; 

cmd.Execute(); 
int? x = cmd.Parameters["@x"].Value is DBNull ? null : (int?)cmd.Parameters["@x"].Value; 

xにはnullが入ります。それを動作させるには、次のような手順を実行する必要があります。

using (var rdr = cmd.ExecuteReader()) { 
    while (rdr.Read()) 
     MaybeDoSomething; 
} 
int? x = cmd.Parameters["@x"].Value is DBNull ? null : (int?)cmd.Parameters["@x"].Value; 

xは、期待通りに1を含みます。

+0

@erikkallen:ストアドプロシージャの呼び出しに関連するすべての結果セットを、出力パラメータまたは戻り値パラメータとともにループする必要があることを明確にしたい場合があります。 –

2

セットアップで他のソリューションを試しても機能しませんでしたが、VB6 & ADO 6.xを使用しています。私はまた、0のproc returnが成功したことを示していることを指摘したい。その慣習を持たない関数も利用可能であることを忘れないでください。 は、MSDNでこれを発見し、それは私のために仕事をした。これを実行するとき

Debug.Print "starting at ..." & TimeValue(Now) 

Dim cn As New ADODB.Connection 
Dim cmd As New ADODB.Command 
'These are two possible connection strings. You could also have Integrated Security instead of these for SqS for security 
'cn.ConnectionString = "Data Source=[yourserver];User ID=[youruser];Password=[yourpw];Initial Catalog=[yourdb];Provider=SQLNCLI10.1;Application Name=[yourapp]" 
cn.ConnectionString = "Data Source=[yours];User ID=[youruser];Password=[yourpassword];Initial Catalog=[Yourdb];Provider=sqloledb;Application Name=[yourapp]" 
cn.Open 

cmd.ActiveConnection = cn 
cmd.CommandText = "AccountExists" 
cmd.CommandType = adCmdStoredProc 
cmd.Parameters.Append cmd.CreateParameter(, adInteger, adParamReturnValue) 
cmd.Parameters.Append cmd.CreateParameter("UserName",adVarChar, adParamInput, 16, UserNameInVB) 

cmd.Execute 
Debug.Print "Returnval: " & cmd.Parameters(0) 
cn.Close 

Set cmd = Nothing 
Set cn = Nothing 

Debug.Print "finished at ..." & TimeValue(Now) 

結果は

0

いくつかの方法は、VBAを使用して値を取り戻すことが可能です(のDebug.Print)イミディエイトウィンドウに表示されます。

  1. レコード
  2. 影響を受けたレコードの数(のみ挿入/更新/削除そうでない場合は-1)
  3. 出力パラメータ
  4. 戻り値

私のコードは4つすべてを示しています。値を返すストアドプロシージャは次のとおりです。

Create PROCEDURE CheckExpedite 
    @InputX varchar(10), 
    @InputY int, 
    @HasExpedite int out 
AS 
BEGIN 
    Select @HasExpedite = 9 from <Table> 
    where Column2 = @InputX and Column3 = @InputY 

    If @HasExpedite = 9 
     Return 2 
    Else 
     Return 3 
End 

ここではExcel VBAで使用するサブセットを示します。 Microsoft ActiveX Data Objects 2.8 Libraryを参照する必要があります。

Sub CheckValue() 

    Dim InputX As String: InputX = "6000" 
    Dim InputY As Integer: InputY = 2014 

    'open connnection 
    Dim ACon As New Connection 
    ACon.Open ("Provider=SQLOLEDB;Data Source=<SqlServer>;" & _ 
     "Initial Catalog=<Table>;Integrated Security=SSPI") 

    'set command 
    Dim ACmd As New Command 
    Set ACmd.ActiveConnection = ACon 
    ACmd.CommandText = "CheckExpedite" 
    ACmd.CommandType = adCmdStoredProc 

    'Return value must be first parameter else you'll get error from too many parameters 
    'Procedure or function "Name" has too many arguments specified. 
    ACmd.Parameters.Append ACmd.CreateParameter("ReturnValue", adInteger, adParamReturnValue) 
    ACmd.Parameters.Append ACmd.CreateParameter("InputX", adVarChar, adParamInput, 10, InputX) 
    ACmd.Parameters.Append ACmd.CreateParameter("InputY", adInteger, adParamInput, 6, InputY) 
    ACmd.Parameters.Append ACmd.CreateParameter("HasExpedite", adInteger, adParamOutput) 

    Dim RS As Recordset 
    Dim RecordsAffected As Long 

    'execute query that returns value 
    Call ACmd.Execute(RecordsAffected:=RecordsAffected, Options:=adExecuteNoRecords) 

    'execute query that returns recordset 
    'Set RS = ACmd.Execute(RecordsAffected:=RecordsAffected) 

    'get records affected, return value and output parameter 
    Debug.Print "Records affected: " & RecordsAffected 
    Debug.Print "Return value: " & ACmd.Parameters("ReturnValue") 
    Debug.Print "Output param: " & ACmd.Parameters("HasExpedite") 

    'use record set here 
    '... 

    'close 
    If Not RS Is Nothing Then RS.Close 
    ACon.Close 

End Sub 
関連する問題