【问题标题】:How to add parameters to a query when query is unknown length查询长度未知时如何向查询添加参数
【发布时间】:2020-04-13 01:17:50
【问题描述】:

我正在处理一个需要将多行添加到 MySQL 表的项目,由于连接的高延迟,我试图在一个命令中添加所有值以节省时间。

到目前为止,我有一个由字符串数组确定的 SQL 查询(每个字符串都是一个“令牌”),这是通过一个 foreach 循环完成的,该循环在插入查询上添加一个值,但是,这种方法由于我找不到在命令中添加参数的方法,因此很难防止 SQL 注入。我不熟悉其他预防注射的方法,但对新想法持开放态度。

query = "INSERT INTO tokenlist(token, user_id) VALUES";
foreach (string tok in tokens)
{
    query += " ('" + tok + "', " + logedinId + "),";
}

if (query != "INSERT INTO tokenlist(token, user_id) VALUES")
{
    query = query.Remove(query.Length - 1);
    query += ";";
    if (OpenConnection() == true) {
        MySqlCommand cmd = new MySqlCommand(query, mysqlcon);
        cmd.ExecuteNonQuery();
        CloseConnection();
    }
}

【问题讨论】:

标签: c# mysql sql sql-injection


【解决方案1】:

使用SqlCommand.Parameters.Add
不要使用foreach,而是使用for,并添加带有附加编号"@tok" + i的参数名称

https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlparametercollection.addwithvalue?view=netframework-4.8

只是示例草稿代码,我没有尝试过:

var tokens = new List<dynamic>() { new { tok = 1, logedinId = 2 }, new { tok = 1, logedinId = 2 } };
var query = "INSERT INTO tokenlist(token, user_id) VALUES";

SqlCommand cmd = new SqlCommand(query, new SqlConnection());

for (int i = 0; i < tokens.Count; i++)
{
    var tokName = $"@tok{i}";
    var logedinIdName = $"@logedinId{i}";
    var token = tokens[i];
    query += $" ({tokName}, {logedinIdName}),";
    cmd.Parameters.Add(new SqlParameter(tokName, SqlDbType.Int)).Value = token.tok;
    cmd.Parameters.Add(new SqlParameter(logedinIdName, SqlDbType.Int)).Value = token.logedinId;
}

if (tokens.Any())
{
    query = query.Remove(query.Length - 1);
    query += ";";

    cmd.ExecuteNonQuery();
}

【讨论】:

  • 介意我编辑您的问题以添加代码示例吗?
  • 另外,不要使用Add,使用AddWithValue,因为Add 命令已在不久前被弃用,现在已过时source
  • @MindSwipe AFAIK only Add(string, object) 已过时。其他重载不是。
  • 您可以执行“cmd.Parameters.Add(tokName, SqlDbType.Int).Value = token.tok;”。不需要“新的 SqlParameter”包装器。
【解决方案2】:
var sql = "INSERT INTO tokenlist(token, user_id) VALUES(@token, @user_id)";
using var cmd = new MySqlCommand(sql, con);
cmd.Parameters.AddWithValue("@token", "tkn");
cmd.Parameters.AddWithValue("@user_id", 3);
cmd.Prepare();
cmd.ExecuteNonQuery();

尝试添加这样的参数。 + 你将避免 sql 注入

【讨论】:

  • 不要使用AddWithValue,使用Add并指定类型、大小/长度和值。使用AddWithValue必须推断类型,可能是错误的。
  • 这并不能完全回答问题。问题是向查询中添加一个动态长的值列表,而不是如何参数化查询
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多