为什么这个 oracle 批量插入不起作用?
我正在尝试将一些数据批量插入到 oracle 数据库中。我按照文档中的示例进行操作。
this.DataBaseAccess = new OracleConnection(connString);
var dataAdapter = new OracleDataAdapter();
var insertCmd = DataBaseAccess.CreateCommand();
insertCmd.CommandType = CommandType.Text;
insertCmd.BindByName = true;
var names = new List<string>();
foreach (DataTable table in product.Contracts.Tables)
{
foreach (DataRow row in table.Rows)
{
names.Add(row["Contract"].ToString());
}
const string InsertContracts = "merge into CONTRACT t " +
"using " +
"(select :name NAME from dual) s " +
"on (t.NAME = s.NAME) " +
"when not matched then " +
"insert (t.NAME) " +
"values (s.NAME)";
insertCmd.CommandText = InsertContracts;
insertCmd.ArrayBindCount = table.Rows.Count;
insertCmd.Parameters.Add(":name", OracleDbType.Varchar2, names, ParameterDirection.Input);
dataAdapter.InsertCommand = insertCmd;
this.DataBaseAccess.Open();
insertCmd.ExecuteNonQuery();
this.DataBaseAccess.Close();
}
好吧,这是行不通的。数据库中没有插入任何内容,我没有收到任何错误消息。
当我不使用批量插入时,一切工作正常(相反,我对数据表中的每一行进行 foreach 循环,并在每次迭代时将 DataRow 插入数据库中)。
更新:我已遵循建议并对我的参数进行了以下更改。
var nameParam = new OracleParameter
{
ParameterName = ":name",
OracleDbType = OracleDbType.Varchar2,
Value = names,
Size = table.Rows.Count,
CollectionType = OracleCollectionType.PLSQLAssociativeArray,
Direction = ParameterDirection.Input
};
我收到此错误:
System.InvalidCastException:无法将“System.String”类型的对象转换为“System.Array”类型。
在 Oracle.DataAccess.Client.OracleParameter.SetStatus(Int32 arraySize)
在 Oracle.DataAccess.Client.OracleParameter.ResetCtx(Int32 arraySize)
在Oracle.DataAccess.Client.OracleParameter.PreBind(OracleConnection conn,IntPtr errCtx,Int32 arraySize)
在 Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
在 \path\share$\Visual Studio 2010\Projects\ImportData-trunk\Gateway\DataGateway.Sql.cs 中的 Gateway.DataGateway.Import(String connString,Product 产品):第 196 行
UPDATE2:ODP.NET 驱动程序很愚蠢(只是不像我预期的那样工作;)
这不起作用,
var names = new List<string>();
它必须是这样的
var names = new string[table.Rows.Count];
I am trying to bulk insert some data into an oracle db. I followed the example in the documentation.
this.DataBaseAccess = new OracleConnection(connString);
var dataAdapter = new OracleDataAdapter();
var insertCmd = DataBaseAccess.CreateCommand();
insertCmd.CommandType = CommandType.Text;
insertCmd.BindByName = true;
var names = new List<string>();
foreach (DataTable table in product.Contracts.Tables)
{
foreach (DataRow row in table.Rows)
{
names.Add(row["Contract"].ToString());
}
const string InsertContracts = "merge into CONTRACT t " +
"using " +
"(select :name NAME from dual) s " +
"on (t.NAME = s.NAME) " +
"when not matched then " +
"insert (t.NAME) " +
"values (s.NAME)";
insertCmd.CommandText = InsertContracts;
insertCmd.ArrayBindCount = table.Rows.Count;
insertCmd.Parameters.Add(":name", OracleDbType.Varchar2, names, ParameterDirection.Input);
dataAdapter.InsertCommand = insertCmd;
this.DataBaseAccess.Open();
insertCmd.ExecuteNonQuery();
this.DataBaseAccess.Close();
}
Well, it does not work. Nothing is inserted into the database, I don't get any error messages.
Everything works fine when i do not use bulk insert (instead i foreach-loop through each row from my DataTables and insert the DataRow into the Database on each iteration).
UPDATE: I have followed the suggestions and made the following changes to my parameter.
var nameParam = new OracleParameter
{
ParameterName = ":name",
OracleDbType = OracleDbType.Varchar2,
Value = names,
Size = table.Rows.Count,
CollectionType = OracleCollectionType.PLSQLAssociativeArray,
Direction = ParameterDirection.Input
};
I get this error:
System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Array'.
at Oracle.DataAccess.Client.OracleParameter.SetStatus(Int32 arraySize)
at Oracle.DataAccess.Client.OracleParameter.ResetCtx(Int32 arraySize)
at Oracle.DataAccess.Client.OracleParameter.PreBind(OracleConnection conn, IntPtr errCtx, Int32 arraySize)
at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
at Gateway.DataGateway.Import(String connString, Product product) in \path\share$\Visual Studio 2010\Projects\ImportData-trunk\Gateway\DataGateway.Sql.cs:line 196
UPDATE2: The ODP.NET driver is stupid (just does not work as i exprected ;)
this does not work
var names = new List<string>();
it has to be this
var names = new string[table.Rows.Count];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要将参数
CollectionType
属性设置为OracleCollectionType.PLSQLAssociativeArray
才能使批量操作正常工作。由于没有
Add()
方法允许您指定这一点,因此您必须在调用Parameters.Add()
后添加以下行:You need to set the parameter
CollectionType
property toOracleCollectionType.PLSQLAssociativeArray
to get bulk operations to work.Since there's no
Add()
method that allows you to specificy this, you would have to add the following line after the call toParameters.Add()
:我必须在列表上使用 ToArray() 方法。
I had to us the ToArray() method on the List.