查询长度未知时如何向查询添加参数

Posted

技术标签:

【中文标题】查询长度未知时如何向查询添加参数【英文标题】: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();
    

【问题讨论】:

MySqlDataAdapter 是一个选项。见:***.com/a/30781587/2419531 【参考方案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 = $"@toki";
    var logedinIdName = $"@logedinIdi";
    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必须推断类型,可能是错误的。 这并不能完全回答问题。问题是向查询中添加一个动态长的值列表,而不是如何参数化查询

以上是关于查询长度未知时如何向查询添加参数的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 Angular 的 $http 的 PUT 方法时向查询字符串添加参数

向查询添加参数的语法

给定特定参数时,如何修复未运行的 SQL 查询? [复制]

使用 Informix 和 Dapper 向查询添加参数失败并出现语法异常

向 Instagram auth redirect_uri 添加查询参数不起作用?

VBA/SQL 参数化查询 - 字段列表中的未知列