[英]Return one row from stored procedure in asp.net
我创建一个存储过程来检索表中的一行:
create procedure LogInUser
@username nvarchar(64),
@password nvarchar(64),
@succeed bit out,
@not_exist_err bit out
as
declare @exist_user nvarchar(64)
select @exist_user = username from users
where username = @username
if @exist_user is null
begin
set @succeed = 0
set @not_exist_err = 1
return
end
else
begin
select * from users
where username = @username and password = @password
end
return
首先,通过使用以下命令验证用户是否存在:
select @exist_user = username from users
where username = @username
然后获取每一列的行:
select * from users
where username = @username and password = @password
但是,通过使用SqlDataReader
,程序将不会进入while循环以检索信息。
它只是不进入循环。 我不明白为什么,即使使用这样的SQL Server执行它,它也确实返回了一行:
declare @succeedResult bit
declare @existErr bit
exec LogInUser @username=admin, @password =admin, @succeed = @succeedResult, @not_exist_err = @existErr
编辑 :执行存储过程的C#方法:
public User LogIn(User usr)
{
SqlConnection conn = A2.Controller.Utils.conn;
SqlCommand loginCmd = new SqlCommand("LogInUser", conn);
loginCmd.CommandType = CommandType.StoredProcedure;
User result = new User();
try
{
conn.Open();
loginCmd.Parameters.Add("@username", SqlDbType.NVarChar).Value = usr.Username;
loginCmd.Parameters.Add("@password", SqlDbType.NVarChar).Value = usr.Password;
loginCmd.Parameters.Add("@succeed", SqlDbType.Bit).Direction = ParameterDirection.Output;
loginCmd.Parameters.Add("@not_exist_err", SqlDbType.Bit).Direction = ParameterDirection.Output;
SqlDataReader dr = loginCmd.ExecuteReader();
if (loginCmd.Parameters["@succeed"].Value != DBNull.Value){
Console.WriteLine("User does not exist");
SqlParameter notExistErr = loginCmd.Parameters["@not_exist_err"];
if (notExistErr.Value != DBNull.Value){
throw new NotExistException("The username or password is incorrect.", "Users");
}
}
while (dr.Read()) {
Console.WriteLine("Looping dr");
result.Username = (string) dr["username"];
result.Password = (string) dr["password"];
result.FirstName = (string) dr["first_name"];
result.MiddleName = (string) dr["middle_name"];
result.LastName = (string) dr["last_name"];
result.ManagerID = (int) dr["manager_id"];
result.IsAdmin = (int) dr["is_admin"];
return result;
}
Console.WriteLine("Done reading");
}
finally {
if (conn.State == ConnectionState.Open) conn.Close();
}
return result;
}
仅在您从过程中的最后一个结果集中读取了最后一行后,才填充输出参数。 因此,这部分将不起作用:
SqlDataReader dr = loginCmd.ExecuteReader();
if (loginCmd.Parameters["@succeed"].Value != DBNull.Value){
此时,未设置loginCmd.Parameters["@succeed"].Value
:只有在您读完最后一行并且dr.Read()
返回false
之后,才会设置该值。
最佳做法是,不要在返回行集的存储过程中使用output
参数。
您可以检查查询是否返回结果,或者不使用dr.HasRows
,它应该看起来像...
SqlDataReader dr = loginCmd.ExecuteReader();
if (!dr.HasRows)
{
Console.WriteLine("User does not exist");
SqlParameter notExistErr = loginCmd.Parameters["@not_exist_err"];
if (notExistErr.Value != DBNull.Value)
{
throw new NotExistException("The username or password is incorrect.", "Users");
}
}
else
{
while (dr.Read())
{
Console.WriteLine("Looping dr");
result.Username = (string) dr["@username"];
result.Password = (string) dr["@password"];
result.FirstName = (string) dr["@first_name"];
result.MiddleName = (string) dr["@middle_name"];
result.LastName = (string) dr["@last_name"];
result.ManagerID = (int) dr["@manager_id"];
result.IsAdmin = (int) dr["@is_admin"];
return result;
}
}
有点奇怪-我希望您的测试看起来像这样:
declare @succeedResult bit
declare @existErr bit
exec LogInUser @username=N'admin', @password =N'admin', @succeed = @succeedResult, @not_exist_err = @existErr
但是,这引出了一个简单的答案。...您是否使用有效(即存在)的用户名和密码来调用函数?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.