在使用SQL Server时,ASP.Net C#中的准备好的语句

5

我是一名ASP.NET C#的初学者,我的数据库是SQL Server。我正在尝试编写一个查询,想要使用预处理语句。

以下是允许用户登录的查询:

    SqlParameter UserName = new SqlParameter("@user", SqlDbType.NVarChar, 30);
    SqlParameter Password = new SqlParameter("@pass", SqlDbType.NVarChar, 20);

    UserName.Value = user.ToLower();
    Password.Value = pass;

    SqlCommand command = new SqlCommand(null, conn);
    command.Parameters.Add(UserName);
    command.Parameters.Add(Password);
    command.CommandText = "SELECT * FROM table_users WHERE user_name = '@user' AND password = '@pass';";

    command.Prepare();
    SqlDataReader reader = command.ExecuteReader();

    bool tmp = reader.HasRows;

tmp 变量的值始终为 FALSE,即使我输入了正确密码的现有用户。

如果我只是删除参数并以这种方式编写查询:

command.CommandText = "SELECT * FROM table_users WHERE user_name = '"+user+"' AND password = '"+ pass+"';";

tmp变量获取了存在用户的TRUE值。

我尝试在INSERT INTO查询中使用此语法,它可以正确运行。

我已经阅读了所有有关将@更改为?的建议,但它并没有奏效。 我遇到了以下错误:

语法不正确。 语句无法准备好。

请帮帮我,谢谢!

1个回答

9
您需要查找文字字面值literals,而非参数的值'@user''@pass';请使用以下代码:
 command.CommandText =
      "SELECT * FROM table_users WHERE user_name = @user AND password = @pass;";

相反,可以考虑使用“加盐哈希”技术,永远不要直接存储密码。

顺便提一下,在这里调用Prepare()并没有什么帮助。我还要推荐一个免费的开源工具dapper-dot-net,使用它可以简化整个过程:

bool authenticated = conn.Query(
    @"select 1 from table_users where user_name = @user and password = @pass",
    new {user = user.ToLower(), pass} ).Any();

或者,如果您想要记录:

var tableUser = conn.Query<TableUser>(
    @"select * from table_users where user_name = @user and password = @pass",
    new {user = user.ToLower(), pass} ).SingleOrDefault();

2
@Jesse 因为大多数数据库现在并不关心:它们对即席查询具有自动查询计划缓存,使得任何差异基本上无法测量。 - Marc Gravell
@MarcGravell,我能不能从Dapper中获得查询字符串,例如“select * from table_users where user_name = user12 and password = 123”,带有值? - Meer
我需要将参数值作为字符串的查询。 - Meer
@Meer 为什么这样做?你想要做什么?参数不是任何字符串的一部分 - 这根本不是通过 TDS(底层协议)传递参数的方式。 - Marc Gravell
我只需要这个来记录日志。 - Meer
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接