【发布时间】:2018-01-27 07:23:22
【问题描述】:
我目前正在开发一个应用程序,我需要在 Oracle (11g) 基础中同时插入几千行(使用 ODP.NET)。 (“批量插入样式”)
这就是我尝试使用 ODP.net 的 Oracle 数据库的数组绑定技术的原因。
这是我的代码:运行它时我没有收到任何错误,但它永远运行也没有任何反应。
如果有人知道问题出在哪里,请告诉我。
感谢您的帮助。
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();
}
【问题讨论】:
-
您是否能够单步执行代码以确定卡在哪一行?如果无法单步执行代码,可以添加一些打印语句吗?
-
嘿 Davmos 感谢您的评论。它卡在“executeNonQuey()”指令上。我已经为查询尝试了许多不同的值,而这个是唯一一个不会引发错误的值。
-
好的,您要插入多少行?也许只是需要很长时间。你可以只用一排试试吗?如果它仍然没有返回,则表可能已被锁定并且它正在等待该锁被释放。如果您执行了先前的插入或更新但未提交,它可能被另一个用户/进程甚至您自己锁定!
-
嘿,我只用了几行试了一下,效果很好。执行大约需要 20 秒。我平均每天要插入 4000 行,所以我会说添加一个日志文件大约需要 30 分钟。有没有更快的方法使用 C# 应用程序在 Oracle 数据库中插入行?无论如何感谢您的帮助 davmos。
-
我发现需要这么多时间的是插入 Clob oracle 数据类型。字符串到 Clob 的内部转换。