我有一个类似这样的存储过程:
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上发布我的问题,只是为了意识到我正在使用哈希值...用户名。现在去户外获取一些氧气。
答案 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();