带有返回值的存储过程

时间:2012-03-12 16:18:16

标签: c# tsql stored-procedures

我有一个类似这样的存储过程:

ALTER PROCEDURE [dbo].[AuthenticateUser]    
    @AzUserName varchar(20),
    @Hash varchar(32),
    @UserId bigint output,
    @Authorized bit output
    ...

并在Management Studio中运行得很好。 这是我的C#代码:

SqlConnection scon = new SqlConnection(connectionString);
SqlCommand authCmd = new SqlCommand("AuthenticateUser", scon);
authCmd.CommandType = System.Data.CommandType.StoredProcedure;

SqlParameter userNameParam = authCmd.Parameters.Add("@AzUserName", System.Data.SqlDbType.VarChar, 20);
                        userNameParam.Value = username;
string hashed = Md5Hash.ComputeHash(username);

SqlParameter hashedParam = authCmd.Parameters.Add("@Hash", System.Data.SqlDbType.VarChar, 32);
hashedParam.Value = hashed;

SqlParameter userIdParam = authCmd.Parameters.Add("@UserId", System.Data.SqlDbType.Int);
userIdParam.Direction = System.Data.ParameterDirection.ReturnValue;

SqlParameter authorizedParam = authCmd.Parameters.Add("@Authorized", System.Data.SqlDbType.Bit);
authorizedParam.Direction = System.Data.ParameterDirection.ReturnValue;

scon.Open();
authCmd.ExecuteNonQuery();
scon.Close();

当我运行它时,我收到以下错误:

{"Procedure or function 'AuthenticateUser' expects parameter '@UserId', which was not supplied."}   System.Exception {System.Data.SqlClient.SqlException}

当我用ParameterDirection.Output替换ParameterDirection.ReturnValue时,我没有收到错误但从未获得过程的值。

更新: 感谢大家的帮助。这个错误比你想象的更微不足道,我在问题中描述过。今天我一直在来回变换ReturnValue到输出很长一段时间没有结果。然后我不得不在SO上发布我的问题,只是为了意识到我正在使用哈希值...用户名。现在去户外获取一些氧气。

3 个答案:

答案 0 :(得分:4)

您必须在每个参数上使用ParameterDirection.Output,该参数已在T-SQL中标记为output。您可以在调用

后访问这些值
authCmd.ExecuteNonQuery();

获取参数的值,如下所示:

authCmd.Parametes["@UserId"].Value

答案 1 :(得分:3)

您对OUTPUT和RETURN值的概念感到困惑。

来自存储过程的RETURN值是每个存储过程的单个整数值,它通过使用RETURN语句在proc中定义,例如

RETURN 1  

存储过程可以有零到多个参数,其中零到多可以定义为OUTPUT。

在您的情况下,您没有显示任何RETURN语句的使用,但您正在使用OUTPUT参数。在SQL Server中,这些更像是输入/输出参数,您需要提供一个值。

通过在调用存储过程后查看参数集合并查看值,可以访问OUTPUT参数的结果值,例如

authCmd.Parameters[2].Value

userIdParam.Value

根据其他答案,您需要使用输出参数方向来实现此

答案 2 :(得分:1)

执行命令后,您可以访问authorizedParam.Value和userIdParam.Value的值。

SqlConnection scon = new SqlConnection(connectionString);
SqlCommand authCmd = new SqlCommand("AuthenticateUser", scon);
authCmd.CommandType = System.Data.CommandType.StoredProcedure;

SqlParameter userNameParam = authCmd.Parameters.Add("@AzUserName", System.Data.SqlDbType.VarChar, 20);
                        userNameParam.Value = username;
string hashed = Zonal.Pie.Core.Common.Utils.Md5Hash.ComputeHash(username);

SqlParameter hashedParam = authCmd.Parameters.Add("@Hash", System.Data.SqlDbType.VarChar, 32);
hashedParam.Value = hashed;

SqlParameter userIdParam = authCmd.Parameters.Add("@UserId", System.Data.SqlDbType.Int);
userIdParam.Direction = System.Data.ParameterDirection.Output;

SqlParameter authorizedParam = authCmd.Parameters.Add("@Authorized", System.Data.SqlDbType.Bit);
authorizedParam.Direction = System.Data.ParameterDirection.Output;

scon.Open();
authCmd.ExecuteNonQuery();
//Access authorizedParam.Value and userIdParam.Value here
scon.Close();