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