0

我在 asp.net 中不断收到运行时 SQL 查询错误。我正在使用 c#。错误总是以“(某些单词)”附近的不正确语法开头。我已经检查并重新检查了我的代码是否有任何语法错误,但从未发现任何错误。在下面的代码中,错误是“用户”附近的语法不正确。请帮忙。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;

public partial class LogIn : System.Web.UI.Page
{
    SqlConnection con = new SqlConnection();
    SqlCommand cmd = new SqlCommand();

    protected void Page_Load(object sender, EventArgs e)
    {
        con.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users        \Sony\Documents\Library\App_Data\Library.mdf;Integrated Security=True;User     Instance=True";
        cmd.Connection=con;
        con.Open();



    }
protected void  txt_user_TextChanged(object sender, EventArgs e)
{

}
protected void  txt_pass_TextChanged(object sender, EventArgs e)
{

}
protected void  btn_log_Click(object sender, EventArgs e)
{
    cmd.CommandText="select count(*) from user where Username='"+txt_user.Text+"' and     Password='"+txt_pass.Text+"'";
        int count =Convert.ToInt16(cmd.ExecuteScalar());
        if (count==1)
        {
            Response.Redirect("Home.aspx");
        }
        else
        {
            Label1.Text="Invalid Username or Password. Please try again..";
        }
}
4

4 回答 4

4

你的错误的原因是这个词user。它是 SqlServer 的保留关键字。
你需要用方括号封装它

select count(*) from [user] ....

话虽如此,现在让我们解决您的代码的最大问题。Sql 注入

cmd.CommandText="select count(*) from [user] where Username=@uname " + 
                "and Password=@upass";
cmd.Parameters.AddWithValue("@uname", txt_user.Text)
cmd.Parameters.AddWithValue("@upass", txt_pass.Text);
int count =Convert.ToInt16(cmd.ExecuteScalar());
......

使用这样的参数化查询可以保护您的应用程序免受恶意输入(请参阅引用的问题)的影响,这些输入可能会破坏(或破坏)存储在数据库中的信息。您还可以避免包含问题字符的输入问题,例如带有单引号或数字小数分隔符的字符串或日期格式困难。

从上面的代码中我可以看到另一个问题。不要将连接存储在全局变量中。如果您在需要时打开连接并在之后关闭,则不会影响性能。它被称为连接池,当您不使用它时,您不会锁定有价值的资源。

所以总结一下:

protected void  btn_log_Click(object sender, EventArgs e)
{

   using(SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=" +
                                 @"C:\Users\Sony\Documents\Library\App_Data\Library.mdf;" + 
                                 @"Integrated Security=True;User Instance=True")
    {
        con.Open();
        using(SqlCommand cmd = new SqlCommand("select count(*) from [user] where "+ 
                                   "Username=@uname and Password=@upass", con)
        {
            cmd.Parameters.AddWithValue("@uname", txt_user.Text)
            cmd.Parameters.AddWithValue("@upass", txt_pass.Text);
            int count =Convert.ToInt16(cmd.ExecuteScalar());
            ......
        }
    }
}
于 2013-03-17T18:41:39.513 回答
1

问题是,“用户”是 SQL 中的保留字。除了注入问题,您的查询应该是:

select ... from [user] where

于 2013-03-17T18:42:20.677 回答
1

'User' 是 SQL server 中的保留关键字。如果你有一个表名'user',你应该在查询中把它放在括号中

select count(*) from [user] where ...
于 2013-03-17T18:42:39.753 回答
0

我完全同意史蒂夫、罗曼和亚历克斯所说的一切。

如果我要添加一些内容,那就是您应该尽量减少临时查询的使用,本示例中已使用该查询。相反,您应该更喜欢将大部分 sql 代码放在 sql 函数和存储过程中,因为这可以极大地提高性能,因为这些查询可以在第一次执行时编译,而在数据库之后执行的时间可以专注于检索数据。对于临时查询,每次都必须编译查询,这实际上可能需要一些时间来处理更复杂的查询。

然后,您可以像这样执行存储过程:

using(SqlCommand cmd = new SqlCommand("dbo.IsValidLogin", con)
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@username", txt_user.Text)
    cmd.Parameters.AddWithValue("@password", txt_pass.Text);
    var isValidLogin =Convert.ToBool(cmd.ExecuteScalar());
    ...
}

如果您在数据库中声明了一个过程,如下所示:

CREATE PROC dbo.IsValidLogin
@username nvarchar(50),
@password nvarchar(50)
AS
BEGIN
  SELECT count(1) 
  FROM [user] 
  WHERE Username=@username
  AND Password=@password
END;

在此处查看 Sql Fiddle 示例。

于 2013-03-17T20:28:06.480 回答