咨询区
GurdeepS:
我有下面的查询语句:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
goALTER PROCEDURE [dbo].[Validate]
@a varchar(50),
@b varchar(50) outputASSET @Password =
(SELECT Password
FROM dbo.tblUser
WHERE Login = @a)RETURN @b
GO
编译都是没有问题的,现在我想执行这条sql并获取最后的返回值,我的代码是这样的。
SqlConnection SqlConn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MyLocalSQLServer"].ConnectionString.ToString());System.Data.SqlClient.SqlCommand sqlcomm = new System.Data.SqlClient.SqlCommand("Validate", SqlConn);string returnValue = string.Empty;try{SqlConn.Open();sqlcomm.CommandType = CommandType.StoredProcedure;SqlParameter param = new SqlParameter("@a", SqlDbType.VarChar);param.Direction = ParameterDirection.Input;param.Value = Username;sqlcomm.Parameters.Add(param);SqlParameter retval = sqlcomm.Parameters.Add("@b", SqlDbType.VarChar);retval.Direction = ParameterDirection.ReturnValue;string retunvalue = (string)sqlcomm.Parameters["@b"].Value;
为了简洁,我去掉了所有的异常判断,不知道为啥 retunvalue
一直都返回 null ,请问这段代码是否有逻辑错误?
回答区
Ravindra Vairagi:
如果你不通过 select 语句 还要获取 存储过程 的返回值,你就必须要指定 ParameterDirection.ReturnValue
枚举并通过 ExecuteScalar
获取返回值,参考我的案例。
CREATE PROCEDURE IsEmailExists@Email NVARCHAR(20)
AS
BEGIN-- SET NOCOUNT ON added to prevent extra result sets from-- interfering with SELECT statements.SET NOCOUNT ON;-- Insert statements for procedure hereIF EXISTS(SELECT Email FROM Users where Email = @Email)BEGINRETURN 0 ENDELSEBEGINRETURN 1END
END
然后是 C# 代码。
GetOutputParaByCommand("IsEmailExists")public int GetOutputParaByCommand(string Command){object identity = 0;try{mobj_SqlCommand.CommandText = Command;SqlParameter SQP = new SqlParameter("returnVal", SqlDbType.Int);SQP.Direction = ParameterDirection.ReturnValue;mobj_SqlCommand.Parameters.Add(SQP);mobj_SqlCommand.Connection = mobj_SqlConnection;mobj_SqlCommand.ExecuteScalar();identity = Convert.ToInt32(SQP.Value);CloseConnection();}catch (Exception ex){CloseConnection();}return Convert.ToInt32(identity);}
这样就可以成功获取 存储过程
的返回值了。
Dean:
如果你的项目采用的是 Dapper 的话,可以参考我的实现。
假如下面是你存储过程的语句
select ID, FILE_NAME from dbo.FileStorage where ID = (select max(ID) from dbo.FileStorage);
Dapper 写法
var data = (_dbConnection.Query<FileUploadQueryResponse>("dbo.insertFile", whateverParameters, commandType: CommandType.StoredProcedure)).ToList();var storedFileName = data[0].FILE_NAME;var id = data[0].ID;
为了能获取返回值,这里我定义了一个复杂类型 FileUploadQueryResponse 来接受存储过程的 return value。
public class FileUploadQueryResponse{public string ID { get; set; }public string FILE_NAME { get; set; }}
点评区
虽然现代开发中很少用存储过程了,但现实项目中还是有很多遗留的 存储过程
存在,所以如何获取返回值还是有必要了解一下。