【问题标题】:Why is my math not working on my SQL Server database?为什么我的数学不适用于我的 SQL Server 数据库?
【发布时间】:2021-05-21 18:01:09
【问题描述】:

我正在开发一个 asp.net Web 应用程序,我正在尝试向它添加一个用户 xp 系统。我有一个与之连接的 SQL Server 数据库,我正在尝试创建一个函数,该函数将为用户提供 5 个经验点。

我查询了已登录的用户,访问了user_xp 列,并尝试将+5 添加到xp 的旧会话变量,然后将其发送回数据库进行存储。这是我的代码,我不确定它有什么问题。

void generateXp()
{
        try
        {
            SqlConnection con = new SqlConnection(strcon);

            if (con.State == ConnectionState.Closed)
            {
                con.Open();
            }

            SqlCommand cmd = new SqlCommand("UPDATE member_master_tbl SET user_xp = @user_xp WHERE " +
                "user_name = '" + Session["username"].ToString().Trim() + "'", con);
            int xp = 5;
            int current_xp = Convert.ToInt32(Session["user_xp"]);
            int new_xp = xp + current_xp;
            string new_xp2 = Convert.ToString(new_xp);

            cmd.Parameters.AddWithValue("user_xp", new_xp2);
        }
        catch (Exception ex)
        {
        }
    }

【问题讨论】:

  • 您的代码容易受到 SQL 注入攻击!永远不要从用户输入构造 SQL 语句。改为使用查询参数,
  • 你为什么要为UPDATESET 部分使用参数-然后切换回WHERE 部分的旧的、糟糕的字符串连接?始终使用参数!
  • 解决参数问题后,您确实需要在某个时候执行查询。
  • 为什么要将数字存储为字符串?
  • 你从来没有执行过命令...?

标签: c# asp.net sql-server database


【解决方案1】:

尝试将 SQL 参数重命名为 @user_xp。

cmd.Parameters.AddWithValue("@user_xp", new_xp2);

我没有可供测试的可访问数据库。此外,您需要在最后添加执行查询的命令。 cmd.ExecuteNonQuery() 话虽如此,学习将数据库查询与存储过程或函数分开是一种很好的做法。

【讨论】:

    【解决方案2】:

    正如其他人所说,您只是忘记执行非查询来运行您设置的命令。

    但是,您可以这样写。您没有提及或注意经验点列是什么数据类型 - 我假设为“int”。

    所以,你的代码块可以这样写:

    using (SqlCommand cmd = new SqlCommand("UPDATE member_master_tbl SET user_xp = @user_xp WHERE user_name = @user",
          new SqlConnection(strcon)))
    {
        cmd.Parameters.Add("@user_xp", SqlDbType.Int).Value = 5 + Session("user_xp");
        cmd.Parameters.Add("@user", SqlDbType.NVarChar).Value = Session("username");
    
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
    }
    

    注意命令对象如何有一个连接对象(所以我们不需要单独的)。

    虽然这里有几个人“感叹”字符串集中构建sql并警告sql注入?

    实际上,为这两个值引入@参数可以清理代码。所以你得到了很好的参数 - 很好的类型检查,你不必记住在字符串周围添加/使用/有引号之类的东西,但不是数字。

    我让 .net 从 session() 转换数字表达式 - 这也可能没问题。

    此外,“使用块”也正确地清理了命令对象和连接对象 - 所以使用块在这里是个好主意。

    【讨论】:

      猜你喜欢
      • 2013-01-10
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 2017-03-04
      • 2011-02-22
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多