【问题标题】:Using Prepared Statement in C# with Mysql在 C# 中使用准备好的语句和 Mysql
【发布时间】:2012-06-17 09:54:37
【问题描述】:

我在我的程序中尝试了准备好的语句,但没有工作。

注释的部分是Prepared Statement部分。当我把它改成普通语句时,一切正常。

谁能告诉我我错过了什么?

非常感谢。

private void btnLogin_Click(object sender, EventArgs e)
{
    MySqlCommand cmd = MySqlConn.cmd;
    //cmd = new MySqlCommand("SELECT * FROM admin WHERE admin_username='@val1' AND admin_password=PASSWORD('@val2')", MySqlConn.conn);
    //cmd.Prepare();
    //cmd.Parameters.AddWithValue("@val1", tboxUserName.Text);
    //cmd.Parameters.AddWithValue("@val2", tboxPassword.Text);
    cmd = new MySqlCommand("SELECT * FROM admin WHERE admin_username='"+tboxUserName.Text+"' AND admin_password=PASSWORD('"+tboxPassword.Text+"')", MySqlConn.conn);

    MySqlDataReader res = cmd.ExecuteReader();
    if (!res.HasRows) { MessageBox.Show("Error! "); res.Close(); return; }
    else
    {
        //do something
    }
    res.Close();
}

【问题讨论】:

  • 什么不完全有效?是否显示错误?

标签: c# mysql prepared-statement


【解决方案1】:

尝试从查询中删除',并在添加参数后使用Prepare

cmd = new MySqlCommand("SELECT * FROM admin WHERE admin_username=@val1 AND admin_password=PASSWORD(@val2)", MySqlConn.conn);
cmd.Parameters.AddWithValue("@val1", tboxUserName.Text);
cmd.Parameters.AddWithValue("@val2", tboxPassword.Text);
cmd.Prepare();

【讨论】:

    【解决方案2】:

    您的解决方案几乎是正确的。但是,由于这是一个登录过程,因此是一项面向安全的任务,因此我也想提出一些建议。

    首先,考虑让您的按钮事件处理程序如下所示:

    private void btnLogin_Click(object sender, EventArgs e)
    {
        if (Login(tboxUserName.Text, tboxPassword.Text))
        {
            // Log in was successful, do something...
        }
        else
        {
            // Log in was NOT successful, inform the user...
        }
    }
    

    这将使应用程序的维护和可读性更容易。然后声明一个名为 Login() 的函数来执行繁重的工作:

    private bool Login(string username, string password)
    {
        try
        {
            MySqlCommand cmd = MySqlConn.cmd;
            cmd = new MySqlCommand(
                "SELECT count(*) FROM admin " + 
                "WHERE admin_username=@username " + 
                "AND admin_password=PASSWORD(@passwd)",
                MySqlConn.conn);
            cmd.Prepare();
            cmd.Parameters.AddWithValue("@username", username);
            cmd.Parameters.AddWithValue("@passwd", password);
            int result = (int)cmd.ExecuteReader();
    
            // Returns true when username and password match:
            return (result > 0);
        }
        catch (Exception e)
        {
            // Optional: log exception details
    
            // Deny log in if an error has occurred:
            return false;
        }
    }
    

    您会在这里注意到一些事情。首先,从您的原始查询字符串中删除了阻止命名参数正常工作的引号。此外,查询返回count() 函数结果,而不是尝试创建包含管理员用户名和密码的结果集。最后,该方法被封装在一个 try-catch 块中,这样在发生错误时,该方法返回false 并拒绝登录。为了便于阅读,我还将查询分解为串联的字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 2013-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多