2011-08-20 34 views
1

我一個創建一個存儲過程中的表檢索一行:在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 

編輯

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; 
} 
+1

您可以添加執行存儲過程的C#代碼部分嗎? – Andomar

+0

@Andomar:我添加了它。 – Amumu

回答

2

輸出參數外核層在讀取過程中最後一個結果集的最後一行之後填充y。因此,這部分將不工作:

SqlDataReader dr = loginCmd.ExecuteReader();    
if (loginCmd.Parameters["@succeed"].Value != DBNull.Value){ 

此時loginCmd.Parameters["@succeed"].Value未設置:您已經閱讀了最後一排後,纔將被設置,並且dr.Read()返回false

作爲最佳實踐,請勿在返回行集的存儲過程中使用output參數。

+0

哇它的工作。非常感謝。我希望我能在MSDN上找到這樣的東西-_- – Amumu

1

:執行該存儲過程的C#方法您可以檢查您的查詢是否返回結果或不使用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; 
    } 
} 
0

東西很奇怪 - 我希望你的測試看起來像這樣:

declare @succeedResult bit 
declare @existErr bit 
exec LogInUser @username=N'admin', @password =N'admin', @succeed = @succeedResult, @not_exist_err = @existErr 

但是,這帶來了一個簡單的答案....你打你的函數與有效(即存在)的用戶名和密碼?

+0

是的,我用有效的用戶名和密碼做了這件事,並且VS確實返回了一行。我在Visual Studio中執行它(但不是SQL Server)。 – Amumu