为什么这个oracle批量插入不起作用?

我正在尝试将一些数据批量插入到oracle db中。 我按照文档中的示例进行操作。

this.DataBaseAccess = new OracleConnection(connString); var dataAdapter = new OracleDataAdapter(); var insertCmd = DataBaseAccess.CreateCommand(); insertCmd.CommandType = CommandType.Text; insertCmd.BindByName = true; var names = new List(); 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(); } 

好吧,它不起作用。 没有任何内容插入数据库,我没有收到任何错误消息。

当我不使用批量插入时,一切正常(相反,我从我的DataTables遍历每一行并在每次迭代时将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 product):第196行

UPDATE2:ODP.NET驱动程序是愚蠢的(只是因为我的表达不起作用;)

这不起作用

 var names = new List(); 

它必须是这样的

 var names = new string[table.Rows.Count]; 

您需要将参数CollectionType属性设置为OracleCollectionType.PLSQLAssociativeArray以使批量操作正常工作。

由于没有允许您具体说明的Add()方法,因此在调用Parameters.Add()之后必须添加以下行:

 insertCmd.Parameters[0].CollectionType = OracleCollectionType.PLSQLAssociativeArray 
 private void BulkCopy(List lsttest_bulk) { try { //ConnectionString = String.Format("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={0})(PORT={1})))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={2})));User Id={3};Password={4};", "ServerAddress", "PortAddress", "DatabaseName", "Username", "Password"); ConnectionString = String.Format("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={0})(PORT={1})))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={2})));User Id={3};Password={4};", "ServerAddress", "PortAddress", "DatabaseName", "Username", "Password"); OracleConnection oraConn = new OracleConnection(ConnectionString); oraConn.Open(); OracleCommand oraCMD = new OracleCommand(); oraCMD.Connection = oraConn; var oracleBulkCopy = new OracleBulkCopy(oraConn) { DestinationTableName = "test_bulk", BulkCopyOptions = OracleBulkCopyOptions.UseInternalTransaction }; DataTable oDataTable = GetDataTableFromObjects(lsttest_bulk); oracleBulkCopy.WriteToServer(oDataTable); oracleBulkCopy.Dispose(); } catch(Exception ex) { Console.WriteLine("failed to write:\t{0}", ex.Message); } } public static DataTable GetDataTableFromObjects(List dataList) where TDataClass : class { Type t = typeof(TDataClass); DataTable dt = new DataTable(t.Name); foreach (PropertyInfo pi in t.GetProperties()) { dt.Columns.Add(new DataColumn(pi.Name)); } if (dataList != null) { foreach (TDataClass item in dataList) { DataRow dr = dt.NewRow(); foreach (DataColumn dc in dt.Columns) { dr[dc.ColumnName] = item.GetType().GetProperty(dc.ColumnName).GetValue(item, null); } dt.Rows.Add(dr); } } return dt; } 

我不得不在List上使用ToArray()方法。

 insertCmd.Parameters.Add(":name", OracleDbType.Varchar2, names.ToArray(), ParameterDirection.Input);