我正在尝试使用参数化命令执行多插入查询,但是我收到了语法异常。 sql中的查询看起来像:
CREATE TEMPORARY TABLE IF NOT EXISTS TEMP_PTO (
ng_id INT,
requested_hours DECIMAL(7,4)
);
INSERT INTO TEMP_PTO VALUES
(1, 0.0000), (2, 1.5000);
我通过以下方式在C#中生成它,其中ptoHours
是包含IEnumerable
和ng_id
的类的requested_hours
。 Queries
是包含查询文字的resx
文件,Queries.PTOLoadTempCommand
= INSERT INTO TEMP_PTO VALUES @v;
:
using (var conn = new MySqlConnection(this.connString))
{
MySqlTransaction trans = null;
try
{
await conn.OpenAsync();
trans = conn.BeginTransaction();
using (var tempCommand = conn.CreateCommand())
{
tempCommand.CommandText = Queries.PTOTempTableCommand;
await tempCommand.ExecuteNonQueryAsync();
}
using (var loadCommand = conn.CreateCommand())
{
loadCommand.CommandText = Queries.PTOLoadTempCommand; //INSERT INTO TEMP_PTO VALUES @v;
loadCommand.Parameters.AddWithValue("@v", String.Join(", " ,ptoHours.Select(p => String.Format("({0}, {1:N4})", p.AgentId, p.UsedVacationHours))));
//Exception thrown here
var affected = await loadCommand.ExecuteNonQueryAsync();
if (affected != entryCount)
throw new Exception("Not All Entries Loaded");
}
trans.Commit();
}
catch (Exception e)
{
if(trans!= null) trans.Rollback();
}
}
查看loadCommand
对象,我可以看到参数@v
的值为(1, 0.0000), (2, 1.5000)
。您是否能够像这样插入或者我是否需要修改函数以一次插入一个?我知道我可以走StringBuilder
路线,但我不能使用参数化的安全性。
答案 0 :(得分:0)
你必须一次做一个。解析查询参数,并且不允许在该位置具有参数。
不需要在一个命令中插入行,如果你需要成功或失败,只需使用事务。
正如你所说,使用StringBuilder或其他字符串连接并不聪明。