我在我的程序中尝试了准备好的声明,但没有工作。
评论的部分是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();
}
答案 0 :(得分:6)
尝试从查询中删除'
,并在添加参数后使用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();
答案 1 :(得分:1)
您的解决方案几乎是正确的。但是,由于这是一个登录过程,因此是一个面向安全的任务,我还想提出一些建议。
首先,考虑使按钮事件处理程序显示如下:
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
并拒绝登录。我还将查询分解为串联字符串,以便于阅读。