0

我正在尝试使用 SQL 创建一个简单的用户名/密码登录,它总是显示为无效。我可以得到一些反馈吗?

 SqlConnection cn;
        cn = new SqlConnection();
        cn.ConnectionString = "Data source=(local); Initial Catalog=INT422Assignment1; Integrated Security=SSPI;";
        cn.Open();
        SqlCommand cmd;
        cmd = new SqlCommand();
        cmd.Connection = cn;
        cmd.CommandText = "SELECT username, pwd FROM myLogin WHERE userNameTB = @username AND passWordTB = @pwd";

        SqlParameter param;
        param = new SqlParameter("@username", SqlDbType.VarChar);
        param.Direction = ParameterDirection.Input;
        param.Value = userNameTB;
        cmd.Parameters.Add(param);

        param = new SqlParameter("@pwd", SqlDbType.VarChar);
        param.Direction = ParameterDirection.Input;
        param.Value = passWordTB;
        cmd.Parameters.Add(param);

        try
        {
            cmd.ExecuteNonQuery();
            cn.Close();
            MessageBox.Show("Login"); 
        }
        catch (Exception ex)
        {
            MessageBox.Show("Invalid");
        }           
    }

它运行,我在命令文本行之后放置了一个断路器,所以我看到它接收来自文本字段的输入,但不知何故它没有将它与数据库中的用户名和密码进行比较。

我感谢你的帮助。

干杯,

埃西

4

5 回答 5

2

如果它总是显示为无效,那应该表明您的查询正在引发异常,因为只有在捕获到异常时才会显示“无效”框。异常的细节是什么?

如果您阅读 上的文档SqlCommand.ExecuteNonQuery(),您会注意到在您的情况下,它没有任何用处:

对于 UPDATE、INSERT 和 DELETE 语句,返回值是受命令影响的行数。当正在插入或更新的表上存在触发器时,返回值包括受插入或更新操作影响的行数以及受一个或多个触发器影响的行数。对于所有其他类型的语句,返回值为 -1。如果发生回滚,则返回值也是 -1。

所以ExecuteNonQuery()不是正确的方法。我怀疑您的异常被抛出与您执行 select 语句的事实有关,由于使用ExecuteNonQuery().

顺便说一句,我会注意到将异常用于控制流程序逻辑被认为是一种不好的做法。异常是针对...异常情况,而不是普通的程序逻辑。此外,在捕获异常时,应尽可能具体。否则,正如您所发现的,您会捕获不应该被捕获的异常,这会导致其他问题。)

我会做这样的事情:

static bool IsAuthenticated( string uid , string pwd )
{
    if ( string.IsNullOrWhiteSpace(uid) ) throw new ArgumentNullException("uid") ;
    if ( string.IsNullOrWhiteSpace(pwd) ) throw new ArgumentNullException("pwd") ;

    bool authenticated ;

    using ( SqlConnection cn = new SqlConnection("Data source=(local); Initial Catalog=INT422Assignment1; Integrated Security=SSPI;") )
    using ( SqlCommand    cmd = cn.CreateCommand() )
    {

        cmd.CommandType = CommandType.Text ;
        cmd.CommandText = @"
SELECT authenticated = count(*)
FROM myLogin
WHERE userNameTB = @username
AND passWordTB = @pwd"
        ;

        cmd.Parameters.AddWithValue( "@username" , uid ) ;
        cmd.Parameters.AddWithValue( "@pwd"      , pwd ) ;

        cn.Open() ;

        authenticated = ((int)cmd.ExecuteScalar()) > 0 ? true : false ;
    cmd.ExecuteNonQuery();

        cn.Close() ;

    }

    return authenticated ;

}
于 2012-11-10T00:44:00.347 回答
0

使用ExecuteScalar()executenonquery 不返回任何内容。或使用 SqlDataAdapter 并填写 DataTable 并查看 DataTable 中是否有任何行或使用 ExecuteScalar() 获取从数据库返回的第一项。您需要从数据库返回的数据。

另一方面,我会使用已经内置了用户登录/注销功能的 ASP.NET 成员资格。我不会构建自己的登录注销网页。

于 2012-11-09T23:37:46.607 回答
0
try
        {
            cmd.ExecuteNonQuery();  //this is for inserting or updating db
            cn.Close();
            MessageBox.Show("Login"); 
        }
        catch (Exception ex)
        {
            MessageBox.Show("Invalid");
        }     

试试这个,而不是使用 SqlDataReader

try{
     SqlDataReader dr = cmd.ExecuteReader()
     While dr.Read() {

      string password = dr("pwd").ToString();
      string username = dr("username").ToString();
      }  
     }

编辑:

 try{
     SqlDataReader dr = cmd.ExecuteReader();
     If dr.HasRows() {
         //Here is your code for good login
      }
     }
于 2012-11-09T23:45:02.120 回答
0

没有结果的 sql 查询不会引发异常。您需要获取结果并检查它们是否为空:if (res.MoveNext())。

于 2012-11-10T00:26:53.663 回答
-2

我认为您不需要此代码中的 @ 符号。

 SqlParameter param;
    param = new SqlParameter("username", SqlDbType.VarChar);
    param.Direction = ParameterDirection.Input;
    param.Value = userNameTB;
    cmd.Parameters.Add(param);

我认为参数名称应该与 pwd 的用户名相同

于 2012-11-09T23:38:15.303 回答