LaGranf LaGranf - 28 days ago 12
C# Question

Array Binding with Oracle(11g) Db and c#

I'm currentlty working on a application for which I need to insert a few thousands lines at the same time in an Oracle (11g) base(using ODP.NET). ("Bulk Insert style")

That's is why I am trying to use the Array binding technique for Oracle data base using ODP.net.

Here is my code : I get no Error while running it, but nothing happens either it runs for ever.

If anyone has an idea of where the problem could come from please tell me.

Thanks for your help.

private static void AddDataTableToDataBase(DataTable tableLog)
{
string[] type = new string[tableLog.Rows.Count];
DateTime[] timestamp = new DateTime[tableLog.Rows.Count];
string[] source = new string[tableLog.Rows.Count];
string[] appName = new string[tableLog.Rows.Count];
string[] action = new string[tableLog.Rows.Count];
string[] fileType = new string[tableLog.Rows.Count];
string[] usr = new string[tableLog.Rows.Count];
int?[] executionTime = new int?[tableLog.Rows.Count];
string[] addMetadata = new string[tableLog.Rows.Count];
string[] explanation = new string[tableLog.Rows.Count];


for (int i = 0; i < tableLog.Rows.Count; i++)
{
type[i] = tableLog.Rows[i][0].ToString();
timestamp[i] = (DateTime)tableLog.Rows[i][1];
source[i] = tableLog.Rows[i][2].ToString();
appName[i] = tableLog.Rows[i][3].ToString();
action[i] = tableLog.Rows[i][4].ToString();
fileType[i] = tableLog.Rows[i][5].ToString();
usr[i] = tableLog.Rows[i][6].ToString();
int executionTimeValue;
if (int.TryParse(tableLog.Rows[i][7].ToString(), out executionTimeValue))
executionTime[i] = executionTimeValue;

addMetadata[i] = tableLog.Rows[i][8].ToString();
explanation[i] = tableLog.Rows[i][9].ToString();
}
string OracleConnectionString = ConfigurationManager.ConnectionStrings["DmsConnection"].ConnectionString;
(OracleConnectionString);
Oracle.DataAccess.Client.OracleConnection conn = new Oracle.DataAccess.Client.OracleConnection(OracleConnectionString);
conn.Open();
Oracle.DataAccess.Client.OracleCommand cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO LOG (TYPE,TIMESTAMP,SOURCE,APPNAME,ACTION,FILETYPE,USR,EXECUTIONTIME,ADDMETADATA,EXPLANATION) VALUES (:TYPE, :TIMESTAMP, :SOURCE, :APPNAME, :ACTION, :FILETYPE, :USR, :EXECUTIONTIME, :ADDMETADATA, :EXPLANATION)";

Oracle.DataAccess.Client.OracleParameter TYPE = new Oracle.DataAccess.Client.OracleParameter("TYPE", Oracle.DataAccess.Client.OracleDbType.NVarchar2, 150, "TYPE");
Oracle.DataAccess.Client.OracleParameter TIMESTAMP = new Oracle.DataAccess.Client.OracleParameter("TIMESTAMP", Oracle.DataAccess.Client.OracleDbType.Date);
Oracle.DataAccess.Client.OracleParameter SOURCE = new Oracle.DataAccess.Client.OracleParameter("SOURCE", Oracle.DataAccess.Client.OracleDbType.NVarchar2, 150);
Oracle.DataAccess.Client.OracleParameter APPNAME = new Oracle.DataAccess.Client.OracleParameter("APPNAME", Oracle.DataAccess.Client.OracleDbType.NVarchar2, 150);
Oracle.DataAccess.Client.OracleParameter ACTION = new Oracle.DataAccess.Client.OracleParameter("ACTION", Oracle.DataAccess.Client.OracleDbType.NVarchar2, 150);
Oracle.DataAccess.Client.OracleParameter FILETYPE = new Oracle.DataAccess.Client.OracleParameter("FILETYPE", Oracle.DataAccess.Client.OracleDbType.NVarchar2, 150);
Oracle.DataAccess.Client.OracleParameter USR = new Oracle.DataAccess.Client.OracleParameter("USR", Oracle.DataAccess.Client.OracleDbType.NVarchar2, 150);
Oracle.DataAccess.Client.OracleParameter EXECUTIONTIME = new Oracle.DataAccess.Client.OracleParameter("EXECUTIONTIME", Oracle.DataAccess.Client.OracleDbType.Int32);
Oracle.DataAccess.Client.OracleParameter ADDMETADATA = new Oracle.DataAccess.Client.OracleParameter("ADDMETADATA", Oracle.DataAccess.Client.OracleDbType.Clob);
Oracle.DataAccess.Client.OracleParameter EXPLANATION = new Oracle.DataAccess.Client.OracleParameter("EXPLANATION", Oracle.DataAccess.Client.OracleDbType.Clob);

TYPE.Direction = ParameterDirection.Input;
TIMESTAMP.Direction = ParameterDirection.Input;
SOURCE.Direction = ParameterDirection.Input;
APPNAME.Direction = ParameterDirection.Input;
ACTION.Direction = ParameterDirection.Input;
FILETYPE.Direction = ParameterDirection.Input;
USR.Direction = ParameterDirection.Input;
EXECUTIONTIME.Direction = ParameterDirection.Input;
ADDMETADATA.Direction = ParameterDirection.Input;
EXPLANATION.Direction = ParameterDirection.Input;

cmd.Parameters.Add(TYPE);
cmd.Parameters.Add(TIMESTAMP);
cmd.Parameters.Add(SOURCE);
cmd.Parameters.Add(APPNAME);
cmd.Parameters.Add(ACTION);
cmd.Parameters.Add(FILETYPE);
cmd.Parameters.Add(USR);
cmd.Parameters.Add(EXECUTIONTIME);
cmd.Parameters.Add(ADDMETADATA);
cmd.Parameters.Add(EXPLANATION);

cmd.Parameters["TYPE"].Value = type;
cmd.Parameters["TIMESTAMP"].Value = timestamp;
cmd.Parameters["SOURCE"].Value = source;
cmd.Parameters["APPNAME"].Value = appName;
cmd.Parameters["ACTION"].Value = action;
cmd.Parameters["FILETYPE"].Value = fileType;
cmd.Parameters["USR"].Value = usr;
cmd.Parameters["EXECUTIONTIME"].Value = executionTime;
cmd.Parameters["ADDMETADATA"].Value = addMetadata;
cmd.Parameters["EXPLANATION"].Value = explanation;

cmd.ExecuteNonQuery();
cmd.Dispose();
conn.Close();
}

Answer Source

I finally found the solution to my problem.

The code above works fine, the only problem is that I use Clob Oracle data type. The internal conversion from string to Clob takes a lot of time.

I ended up truncating the strings that were too long and now it works fine and it is really fast. (Just a few seconds to insert 4000 records).