在 C# 中使用带有参数的 for 循环更新 table

update a table by using for loop with parameters in C#

我有一个 table 有一些像

这样的列

现在我想用for循环来设置

out_0 = 0, 
out_1 = 1, 
out_2 = 2, 
out_3 = 3, 
out_4 = 4

所以我用这样的代码更新它

string sql = "update exchange_out set @column = @id where member_id = 6;";

SqlCommand cmd = new SqlCommand(sql, connet);
cmd.Parameters.Add("@column", SqlDbType.NVarChar);
cmd.Parameters.Add("@id", SqlDbType.Int);

int n = 0;

for (int i = 0; i < 5; i++)
{
    cmd.Parameters["@column"].Value = "out_" + i;
    cmd.Parameters["@gid"].Value = i;

    n = cmd.ExecuteNonQuery();                
    MessageBox.Show("" + n);
}

但它没有向 table 写入任何数据,而 它实际上做了五次更新,因为消息框 returns “1” 五次。

最后我通过

解决了这个问题
    for (int i = 0; i < 5; i++){
        sql = string.Format("update exchange_out set {0} = {1} where member_id = 6", "out_" + i, i);
}

但我还是想知道为什么加了参数还是不行?

如有任何回复,我们将不胜感激。 :)

I'm still wondering why it didn't work by adding parameters?

table等标识符和列名不能通过这种方式参数化,只能是数据。您的尝试有效地运行了如下查询:

update exchange_out set 'out_1' = 1 where member_id = 6;

任何编程语言都一样:

var data1 = "hello";
var whichData = "1";

Console.WriteLine(data+whichData); //it doesn't compile; you cannot programmatically build a variable name `data1` in this way

您找到的方法是合理的唯一方法,但您仍应参数化 data:

using var cmd = new SqlCommand(sql, connet);
cmd.Parameters.Add("@data", SqlDbType.NVarChar);
cmd.Parameters.Add("@id", SqlDbType.Int);

for (int i = 0; i < 5; i++){
    sql = string.Format("update exchange_out set out_{0} = @data where member_id = @id", i);
    cmd.CommandText = sql;
    cmd.Parameters["@data"].Value = ...
    cmd.Parameters["@id].Value = 6;

    ...

您也可以从 SQL 存根开始,例如 "UPDATE t SET " 并重复连接标识符和参数:

using var cmd = new SqlCommand(sql, connet);
cmd.Parameters.Add("@data", SqlDbType.NVarChar);
cmd.Parameters.Add("@id", SqlDbType.Int);
var sql = "UPDATE exchange_out SET ";
for (int i = 0; i < 5; i++){
    sql += string.Format("out_{0} = @data{0},", i);
    cmd.Parameters["@data"+i].Value = ...
}
sql = sql.TrimEnd(',');
sql +=  " where member_id = @id";
cmd.Parameters["@id"].Value = 6;
cmd.CommandText = sql;

    ...

这会在一次操作中完成更新,运行 像 UPDATE t SET out_1 = @data1, out_2 = @data2 ...

这样的查询

这些可以避免 SQL 注入,因为您的代码控制着整个 SQL;用户没有任何能力提供 '; DROP TABLE Students;-- 作为 {0} 进入标识符 在这种情况下 但请注意您不要安排这是可能的(不要让用户提供标识符文本)..

你的 non-parameter 尝试也是安全的 SQL 注入 在这种情况下 凭借插入你控制的整数,而不是你不控制的字符串' t,但请注意,您不会普遍应用该技术,并且有一天会包含 user-suppied 个字符串。如果你确实发现自己在那个 suitable 中,你应该使用类似用户输入白名单的东西 - 用户提供的任何未列入白名单的字符串标识符不应该放在 SQL