【问题标题】:Add SQL Parameters inside the loop, excecute outside the loop. (Single query multi-insert with parameters in C# SQL Client)在循环内添加 SQL 参数,在循环外执行。 (C# SQL 客户端中带参数的单查询多插入)
【发布时间】:2019-09-30 02:55:07
【问题描述】:

所以,想要进行多行插入查询,我需要用我拥有值的循环内的值替换键。

它通过将值硬编码到查询字符串中来工作,但我需要使用“cmd.Parameters.AddValue()cmd.Parameters.AddWithValue()”来完成它,因为我需要防止 SQL 注入。

所以,我的代码是这样的:

         string query = "insert into dbo.Foo (column1, column2, column3) values ";    
         SqlCommand cmd
            foreach (line in rowsArray) {
                cmd.Parameters.Clear();
                cmd = new SqlCommand(query, cnn); //So, the problem is this override
                query += "(@key1, @key2, @key3), ";

                cmd.Parameters.AddWithValue("@key1", line.value1);
                cmd.Parameters.AddWithValue("@key2", line.value2);
                cmd.Parameters.AddWithValue("@key3", line.value3);
            } 
         query = query.Substring(0, query.Length-2); //Last comma
         cmd.ExecuteNonQuery();
         cnn.Close();

我想在循环外ExecuteNonQuery();,只插入一个。

有什么想法吗?

我想过创建一个循环,在其中添加带有标识符的字符串中的键,然后用相同的 id 替换所有这些键以迭代另一个循环,但我认为这不是非常有效或好的做法。

【问题讨论】:

  • 给参数唯一编号索引,而不是1, 2, 3重复。
  • 我可能只是创建一个事务,使用多个ExecuteNonQuery 调用,然后在最后提交事务。可能有更好的方法,但我至少希望它能奏效。否则,您需要在 SQL 中创建多个插入语句,并使用唯一命名的参数。
  • @JonSkeet 但是Execute方法每次调用都会攻击数据库吗?
  • 如果你喜欢,可以使用SqlBulkCopy进行批量插入,使用这个链接:stackoverflow.com/questions/3913371/sqlbulkcopy-from-a-list
  • SQL Server 可以有效处理的查询长度有限制,VALUES 子句的硬限制为 1000 行,并且像这样的语句(具有许多不同的参数计数)会污染计划缓存。通常这种方法是不值得的;使用多语句事务、表值参数或SqlBulkCopy 类。 (和don't use AddWithValue)。

标签: c# sql sql-server sqlclient


【解决方案1】:

我最终决定做两个循环,因为它的效果比预期的要好。

我想过创建一个循环,在其中添加带有标识符的字符串中的键,然后用相同的 id 替换所有这些键以迭代另一个循环,但我认为这不是非常有效或好的做法。

通过这种方法,我完成了字符串查询,然后添加了值。我给了键 id,这样我就可以在下一个循环中使用相同的 id 按顺序将它们替换为值。

            string query = "insert into dbo.Foo (column1, column2, column3) values ";    
         
            int id = 0;
            foreach (line in rowsArray) {
                query += "(@key1"+id+", @key2"+id+", @key3"+id+"), ";
                id++;
            }
            query = query.Substring(0, query.Length-2); //Last comma


            SqlCommand cmd = new SqlCommand(query, cnn);
            id = 0;
            foreach (line in rowsArray) {
                cmd.Parameters.AddWithValue("@key1"+id, line.value1);
                cmd.Parameters.AddWithValue("@key2"+id, line.value2);
                cmd.Parameters.AddWithValue("@key3"+id, line.value3);
            } 
         
            cmd.ExecuteNonQuery();
            cnn.Close();

另外,提到 SqlBulkCopy 的存在,它允许上传 DataTables 并将产生更清晰的代码。

【讨论】:

  • 而且你仍然拒绝学习如何正确参数化——不要使用addwithvalue
  • @SMor 这很有趣,但这不是问题的原因,我不是在问这个问题,所以不要对这个话题无礼,因为它对解决方案没有影响。我不拒绝学习任何东西,只是以前没有人告诉我“AddWithValue 是邪恶的”。
  • 地狱卡洛斯,您是否考虑过使用“用户定义的表格类型”,这样您可以创建一个表格并将您的值插入表格中,然后将您的表格作为参数发送到您的 SP 中,使用 select 语句进行插入
猜你喜欢
  • 1970-01-01
  • 2018-08-12
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-17
  • 1970-01-01
相关资源
最近更新 更多