Por que esse inserto em massa do oracle não funciona?
Estou tentando inserir em massa alguns dados em um oracle db. Eu segui o exemplo na documentação.
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();
}
Bem, isso não funciona. Nada é inserido no banco de dados, não recebo nenhuma mensagem de erro.
Tudo funciona bem quando eu não uso a inserção em massa (em vez disso, foreach-loop através de cada linha do meu DataTables e insiro o DataRow no banco de dados em cada iteração).
ATUALIZAÇÃO: Segui as sugestões e fiz as seguintes alterações no meu parâmetro.
var nameParam = new OracleParameter
{
ParameterName = ":name",
OracleDbType = OracleDbType.Varchar2,
Value = names,
Size = table.Rows.Count,
CollectionType = OracleCollectionType.PLSQLAssociativeArray,
Direction = ParameterDirection.Input
};
Eu recebo este erro:
System.InvalidCastException: Não foi possível converter o objeto do tipo 'System.String' para o tipo 'System.Array'.
em Oracle.DataAccess.Client.OracleParameter.SetStatus (Int32 arraySize)
em Oracle.DataAccess.Client.OracleParameter.ResetCtx (Int32 arraySize)
em Oracle.DataAccess.Client.OracleParameter.PreBind (OracleConnection conn, IntPtr errCtx, Int32 arraySize)
em Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery ()
em Gateway.DataGateway.Import (String connString, produto do produto) em \ path \ share $ \ Visual Studio 2010 \ Projects \ ImportData-trunk \ Gateway \ DataGateway.Sql.cs: linha 196
UPDATE2: O driver ODP.NET é estúpido (simplesmente não funciona como eu expressei;)
isso não funciona
var names = new List<string>();
tem que ser isso
var names = new string[table.Rows.Count];