asp.net c#中的SQL运行时错误

本文关键字:SQL 运行时错误 中的 net asp | 更新日期: 2023-09-27 18:04:27

我在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..";
        }
}

asp.net c#中的SQL运行时错误

错误的原因是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());
            ......
        }
    }
}

问题是,"user"在SQL中是一个保留字。除了注入问题,您的查询应该如下:

select ... from [user] where

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

的括号里。
select count(*) from [user] where ...

我完全同意Steve, Roman和Alex所说的。

如果我应该添加一些东西,那就是您应该尽量减少ad-hoc查询的使用,就像在这个例子中使用的那样。相反,您应该倾向于将大部分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;