使用 ExecuteNonQuery 在 oracle 中一次执行多个插入
Performing multiple inserts at once in oracle with ExecuteNonQuery
我正在尝试像这样一次执行多个插入
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'
即使我可以手动执行来自 sql 开发人员的生成的查询也没有问题。
我以前用 sqlserver 和 sqlite 做过这个,我没有遇到任何问题。
为什么会这样?有没有更干净的方法?
这里是生成的sql:
insert into myTable (colA, colB) values (72520,2452); insert into myTable (colA, colB) values (73293,2453)
在 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 答案)如果
- 你必须插入字符串(SQL注入)
- 您有很多记录要插入(批量操作工作 更快)
- 您经常调用(硬解析,参见https://blogs.oracle.com/sql/improve-sql-query-performance-by-using-bind-variables)
why this happens?
Oracle 不允许在一个命令中执行多个语句。
SQL 开发人员会将您的字符串拆分为多个语句并依次执行每个语句 运行 它们作为多个命令,
is there a cleaner way?
使用 batch/bulk 插入:
- Bulk Insert to Oracle using .NET
- OracleBulkCopy does not insert entries to table
这样您就可以使用绑定值,而不是将您的插入语句构建为一个巨大的字符串。
这不是你应该做的。首选方式是这样的:
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();
}
我正在尝试像这样一次执行多个插入
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'
即使我可以手动执行来自 sql 开发人员的生成的查询也没有问题。
我以前用 sqlserver 和 sqlite 做过这个,我没有遇到任何问题。
为什么会这样?有没有更干净的方法?
这里是生成的sql:
insert into myTable (colA, colB) values (72520,2452); insert into myTable (colA, colB) values (73293,2453)
在 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 答案)如果
- 你必须插入字符串(SQL注入)
- 您有很多记录要插入(批量操作工作 更快)
- 您经常调用(硬解析,参见https://blogs.oracle.com/sql/improve-sql-query-performance-by-using-bind-variables)
why this happens?
Oracle 不允许在一个命令中执行多个语句。
SQL 开发人员会将您的字符串拆分为多个语句并依次执行每个语句 运行 它们作为多个命令,
is there a cleaner way?
使用 batch/bulk 插入:
- Bulk Insert to Oracle using .NET
- OracleBulkCopy does not insert entries to table
这样您就可以使用绑定值,而不是将您的插入语句构建为一个巨大的字符串。
这不是你应该做的。首选方式是这样的:
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();
}