SQLCommand.ExecuteScalar() - 为什么抛出System.NullReferenceException?

时间:2009-03-24 02:50:54

标签: .net exception sqlcommand

有没有人能注意到以下功能可能出现的问题:

public string Login(string username, string password)
    {
        string result = "";
        string select = "SELECT user_id FROM [user] WHERE username = @username AND password = @password";
        SqlConnection conn = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand(select, conn);
        cmd.Parameters.AddWithValue("username", username);
        cmd.Parameters.AddWithValue("password", password);
        int userID = 0;
        try
        {
            conn.Open();
            userID = (int)cmd.ExecuteScalar();
            if(userID > 0)
            {
                result = addSession(userID);
            }
        }
        catch(Exception ex)
        {
            string sDummy = ex.ToString();
        }
        return result;
    }

不知道为什么行`userID =(int)cmd.ExecuteScalar();抛出异常。

由于

6 个答案:

答案 0 :(得分:5)

表中很可能没有包含该用户/密码的行。 ExecuteScalar的文档说如果结果集为空则返回null,并且不能将null转换为int。

答案 1 :(得分:1)

您应该考虑修改这段代码:

try
{
    conn.Open();
    userID = (int)cmd.ExecuteScalar();
    if(userID > 0)
    {
        result = addSession(userID);
    }
 }
 catch(Exception ex)
 {
    string sDummy = ex.ToString();

 }
 finally // add this to ensure the connection is closed!
 {
     if (conn != null)
       conn.Close();
 }

答案 2 :(得分:1)

如果在数据库中找不到提供的凭据,标量是否可能为空?

答案 3 :(得分:0)

不确定,但您可能需要“@”作为参数名称:

...AddWithValue("@username", username);

答案 4 :(得分:0)

我在使用SqlCE时遇到了同样的问题。我找到的解决方案(在我开始输入密码正确...>。>之后),首先将ExecuteScalar结果作为对象收集,然后转换为第二个。 Litterally,使用

Object o = cmd.ExecuteScalar(); 
int id = Convert.ToInt32(o); 

而不是

int id = (int) cmd.ExecuteScalar(); 

是工作和崩溃之间的区别。我不知道为什么会这样......

答案 5 :(得分:0)

我没有看到任何hashbytes功能,但在这里:

如果在后端SQL服务器上使用hashbytes函数,则将密码输入转换为二进制数组。 Hashbytes返回varbinary。因此,如果您传递空终止符,则哈希值不会相同。就像在SQL hashbytes('SHA2_512,'stuff')中一样,就像哈希',' t',直到' f'。没有' \ 0'在末尾。但是如果你在sqlcommand对象中将其参数化为字符串,它将添加' \ 0'最后,SQL将计算零。因此,如果使用Encoding类转换为二进制数组,则参数将只是不带空终止符的字符串。 我遇到了类似的问题,我以这种方式解决了使用addwithvalue及其值为二进制的问题。

但是,你知道executecalar返回一个对象。如果查询返回零行,则该对象将为NULL,并且您无法将NULL对象转换或转换为任何对象。所以在if语句中说"如果returnsobject == null,那么你不会被authed。别的...."