繁体   English   中英

在C#和MySQL中使用预准备语句

[英]Using Prepared Statement in C# with Mysql

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

注释的部分是“准备报表”部分。 当我将其更改为常规语句时,一切都正确。

有人能告诉我我错过了什么吗?

非常感谢。

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();
}

尝试从查询中删除' ,并在添加参数后使用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();

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

首先,考虑使按钮事件处理程序显示如下:

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并拒绝登录。 我还将该查询分为一个串联的字符串,以便于阅读。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM