最近我遇到的情况是,我的代码显示类似于以下内容:
string insertSql = "";
foreach (int animalType in new[] { 1,2,3 })
insertSql += String.Format("INSERT INTO `animalType` (type) VALUES ({0}); ", animalType);
每次插入次数很少(1-3)。
感觉“糟糕”,但我不能确切地说为什么。有什么想法吗?
基本上许多sql插入连接成一个字符串。 Afaik有3个理由不通过字符串连接向sql添加值:安全性,格式化问题,执行速度。因为参数是整数,所以不能进行任何sql注入。没有格式问题需要处理。另外,因为这些是插入,所以sql server不会重用句柄(它存储并可选择重用查询句柄)。
此外,桌面上没有触发器。
通常可以通过使用union INSERT INTO animalType (type) (SELECT 1 UNION SELECT 2 UNION SELECT 3)
进行单个插入来改进它。
我知道可以使用数据表添加到参数化查询中,或者可以使用xml但是它只是让代码更长更难读? 我只是没有任何反对它的真实论据。
以这种方式动态创建参数化查询是否有任何意义:
string insertSql = "";
SqlCommand command = new SqlCommand();
var types = new[] { 1, 2, 3 };
for (int i = 0; i < types.Length; i++)
{
insertSql += String.Format("INSERT INTO `animalType` (type) VALUES (@typeParam{0}); ", i);
command.Parameters.AddWithValue("typeParam" + i, types[i]);
}
对于连接sql整数值而不使用参数化查询的人,我能说什么呢,因为他的方法比较简单? :)
答案 0 :(得分:2)
你可以对它进行分析以确定,但我敢打赌你不会因多次执行一个命令而导致显着性能下降:
string insertSql = "INSERT INTO animalType (type) VALUES (@type)";
var types = new[] { 1, 2, 3 };
using(SqlCommand command = new SqlCommand(insertSql, conn))
{
foreach(var type in types)
{
command.Parameters.AddWithValue("@type", type);
command.ExecuteNonQuery();
}
}
对于连接sql整数值而不使用参数化查询的人,我能说什么呢,因为他的方法比较简单?
我的论点是,使代码容易受到SQL注入和格式化问题的影响不会太大。在您添加字符串列的那一刻,代码很容易受到攻击,并且很有可能是下一个人来添加字符串列不会花时间将查询转换为参数化只是为了添加一列。
答案 1 :(得分:1)
这是在某些情况下可接受的有效代码。它不是最佳的,但没有安全问题。 SQL Server通常会自动参数化像这样的简单查询(因为很多开发人员都会这样做......)。
这里有三个相关的优化:
UNION ALL
和TVP提案可以完成此任务。每个语句都有一些CPU开销。无论您喜欢简单的方法,还是更快,更复杂的方法,只有您才能做出权衡。