【问题标题】:SQL Parameters Inside A Loop循环内的 SQL 参数
【发布时间】:2014-07-03 18:38:05
【问题描述】:

我有一个列表,我要从中提取内容以插入数据库。这不会是一个网络应用程序,所以我一直在做如下:

string sqlStorage = (null,"asd"),

for (int i = 1; i < listsize; )
{

sqlStorage = sqlStorage + "(null,someVariableFromLoop)";

i++

}

string connString = "Server=localhost;...........";

MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = @"INSERT INTO table1 VALUES " + tempSQLStorage;

etcetc...

然而

"someVariableFromLoop"

是包含各种可怕的代码破坏字符的大量文本。引号等。

所以我查看了参数(我知道我应该执行 SQL 的方式,我知道),但是我无法找到将这些参数存储在循环中的方法。我不想每次迭代都访问数据库。我尝试了一些类似

的东西

"@variable"+i.toString();

但根本无法让它工作。

那么有人知道我将如何存储参数和执行查询吗?提前致谢!

【问题讨论】:

  • 我会考虑参数的第一个原因是提高安全性。如果您接受来自 UI 的输入并将其直接推送到数据库,那么您很容易受到 SQL 注入攻击。
  • 假设这是 SQL Server,您应该查看表值参数或(如果它的行数非常多)SQLBulkCopy api。
  • @EricJ。 100% 同意。然而,这只是一个本地托管的脏小脚本,用于处理我拥有的一些数据。
  • @RBarryYoung 抱歉忘记添加它是 mySQL
  • 你的for循环比较奇怪,通常的写法是for (int i = 0; i &lt; listsize; i++),而不是在循环内使用i++

标签: c# sql loops sqlparameter


【解决方案1】:

所以我查看了参数(我知道我应该执行 SQL 的方式,我知道),但是我无法找到将这些参数存储在循环中的方法。我不想每次迭代都访问数据库。我尝试了一些类似的东西 "@variable"+i.toString(); 但根本无法让它工作。

那么,您收到的错误是什么?因为你就是这样做的。这是 MSSQL 的示例,我知道该技术有效,因为我以前做过类似的事情:

int i = 0;
List<string> clauses = new List<string>() {"(@key0, @value0)"};
List<SqlParameter> paramList = new List<SqlParameter> {
    new SqlParameter("@key0", DBNull.Value), 
    new SqlParameter("@value0", "asd")
};
for (i = 1; i < listSize; i++) {
    clauses.Add("(@key" + i + ", @value" + i + ")");
    paramList.Add(new SqlParameter("@key" + i, someKey));
    paramList.Add(new SqlParameter("@value" + i, someValue);
}
SqlConnection conn = new SqlConnection(connString);
SqlCommand command = new SqlCommand(conn, @"INSERT INTO table1 VALUES " + String.Join(", ", clauses);
foreach(SqlParameter param in paramList) command.Parameters.Add(param);
command.ExecuteNonQuery();

注意,上面的代码又快又脏。显然,using 语句和各种其他最佳实践也应该用于生产代码。

另请参阅:How do you use the MySql IN clause。它有一个动态创建参数并将参数传递给查询的示例,但是对于 SELECT...IN 子句与 INSERT...VALUES。

【讨论】:

    【解决方案2】:

    为确保代码安全(并避免格式错误的查询),请使用带参数的 SQL 命令对象。为每条记录执行一次命令并没有什么可怕的错误——通过网络进行往返会产生一些额外的开销,但如果文本很长,你可能不得不这样做,因为查询确实有字符限制。

    【讨论】:

    • 不同意可忽略的开销 - 与数据库的网络通信不可忽略。
    • 假设连接池和执行计划重用,您能否帮助我了解发出一个具有多个值列表的插入与每个具有一个值列表的多个插入相比会有哪些额外开销?除非有人告诉我,否则我会继续认为网络通信几乎相同(除了 INSERT 关键字和字段列表的多个实例)。如果我错了,请解释。
    • 往返本身就是增加性能的原因。如果 OP 插入 100 个项目,那么执行 100 次往返将花费明显更长的时间。
    • 很公平。我希望我有一个方便的基准来查看多次往返将百分比方式添加到整体执行时间中。我怀疑它很小,但绝对不是零,所以我在上面编辑了我的答案。
    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多