使用ExecuteNonQuery在oracle中一次执行多个插入

时间:2018-04-10 12:42:24

标签: c# oracle dbcommand

我试图像这样一次执行多个插入

var mydict =  new Dictionary<int, int> { { 1, 2 }, { 3, 4 } };

var query = string.Join("; ", mydict.Select(x => $"insert into myTable (colA, colB) values ({x.Key},{x.Value})"));

using(var connection = new new OracleConnection(dbConnectionString))
{
    var command = connection.CreateCommand();
    command.CommandText = query;
    command.ExecuteNonQuery();
}     

但是我得到了Oracle.ManagedDataAccess.Client.OracleException: 'ORA-00911: invalid character',即使我可以从sqldeveloper手动执行生成的查询而没有任何问题。

我过去用sqlserver和sqlite做过这个,我没有问题。

为什么会这样?有更干净的方式吗?

这是生成的sql:

insert into myTable (colA, colB) values (72520,2452); insert into myTable (colA, colB) values (73293,2453)

3 个答案:

答案 0 :(得分:3)

如果是 Oracle ,您应该生成匿名阻止,例如:

 begin -- wrap in begin .. end
   insert into myTable (colA, colB) values (72520, 2452); 
   insert into myTable (colA, colB) values (73293, 2453); -- do not forget last ;
 end;

在你的情况下

var query = 
  "begin " + 
     string.Join("; ", mydict
       .Select(x => $"insert into myTable (colA, colB) values ({x.Key},{x.Value})")) + 
  "; end;";

免责声明:请勿执行此操作(但请执行bulk insert,请参阅 MT0 答案)

  1. 您必须插入字符串( SQL注入
  2. 您需要插入大量记录(批量操作更快
  3. 您经常执行呼叫(硬解析,请参阅https://blogs.oracle.com/sql/improve-sql-query-performance-by-using-bind-variables

答案 1 :(得分:1)

  

为什么会这样?

Oracle不允许在一个命令中执行多个语句。

SQL开发人员会将您的字符串拆分为多个语句,然后依次将它们作为多个命令执行,

  

有更清洁的方式吗?

使用批量/批量插入:

这样您就可以使用绑定值,而不是将insert语句构建为一个巨大的字符串。

答案 2 :(得分:1)

这不是你应该这样做的方式。首选方式是这样的:

var command = connection.CreateCommand();
command.CommandText = "insert into myTable (colA, colB) values (:ColA, :ColB)";
command.Parameters.Add("ColA", OracleDbType.Int64, ParameterDirection.Input);
command.Parameters.Add("ColB", OracleDbType.Int64, ParameterDirection.Input);

foreach ( var entry in mydict ) {
   command.Parameters["ColA"].Value = entry.Key;
   command.Parameters["ColA"].Value = entry.Value;
   command.ExecuteNonQuery();
}