在参数化查询

时间:2015-08-11 18:02:11

标签: c# mysql

我正在尝试使用参数化命令执行多插入查询,但是我收到了语法异常。 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是包含IEnumerableng_id的类的requested_hoursQueries是包含查询文字的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路线,但我不能使用参数化的安全性。

1 个答案:

答案 0 :(得分:0)

你必须一次做一个。解析查询参数,并且不允许在该位置具有参数。

不需要在一个命令中插入行,如果你需要成功或失败,只需使用事务。

正如你所说,使用StringBuilder或其他字符串连接并不聪明。