使用DataTable中的OracleDataAdapter更新记录并将其插入Oracle表

一个从新手到c#的问题,并为它的长度道歉。 我有以下情况。 我有一个小型控制台应用程序,通过连接到外部系统来填充数据表,然后需要更新现有记录并将新的记录插入到oracle表中。 数据表中的列的名称与oracle表列的名称不同,而且顺序不同。 我在这里阅读了另一篇文章,其中有类似的场景(从文件加载到表中),并且提到使用OracleDataAdapter进行更新/插入是可行的。 简化的数据表和oracle表是

DataTable table = new DataTable(); table.Columns.Add("Product", typeof(String)); table.Columns.Add("Price", typeof(double)); table.Columns.Add("Effective_Date", typeof(DateTime));

//sample data table.Rows.Add("abcd", 1.011, DateTime.Today); table.Rows.Add("efg", 1.00, DateTime.Today); table.Rows.Add("hijk", 20, DateTime.Today);

oracle表具有结构

ITEM VARCHAR2(20 BYTE) NOT NULL ENABLE, EFF_DATE DATE, VALUE NUMBER

我已经尝试使用以下代码来使用数据表和适配器来更新oracle表,但我遗漏了一些东西。 我也想知道我是不是在叫错树。 我见过的大多数使用dataadapter的例子首先从表中进行选择,然后将结果放入网格中,用户可以在其中添加,更新,插入或删除记录,然后使用dataadapter更新表。 在我的情况下,我想知道如果数据表中的所有记录都被视为插入,我是否可以使它工作,因为数据表和oracle表之间没有连接。

我正在使用Oracle.ManagedDataAccess.Client连接并执行更新

 public static void UpdateOrSaveItems(DataTable dt) { String insert_statement, update_statement, select_statement; select_statement = "SELECT * from items"; insert_statement = "INSERT INTO items (item, eff_date, value) values (:pInsItem,:pInsEffDate,:pInsValue)"; update_statement = "UPDATE items set eff_date = :pUpdEffDate, value = :pUpdValue where item = :pUpdItem"; using (OracleConnection conn = theDatabase.ConnectToDatabase()) { using (OracleDataAdapter oraAdapter = new OracleDataAdapter(select_statement, conn)) { //build update/insert commands and parameters oraAdapter.UpdateCommand = new OracleCommand(update_statement, conn); oraAdapter.InsertCommand = new OracleCommand(insert_statement, conn); oraAdapter.UpdateCommand.BindByName = true; oraAdapter.InsertCommand.BindByName = true; OracleParameter pUpdItem = new OracleParameter("pUpdItem", OracleDbType.Varchar2); pUpdItem.SourceColumn = dt.Columns[0].ColumnName; OracleParameter pUpdEffDate = new OracleParameter("pUpdEffDate", OracleDbType.Date); pUpdEffDate.SourceColumn = dt.Columns[2].ColumnName; OracleParameter pUpdValue = new OracleParameter("pUpdValue", OracleDbType.Double); pUpdValue.SourceColumn = dt.Columns[1].ColumnName; OracleParameter pInsItem = new OracleParameter("pInsItem", OracleDbType.Varchar2); pUpdItem.SourceColumn = dt.Columns[0].ColumnName; OracleParameter pInsEffDate = new OracleParameter("pInsEffDate", OracleDbType.Date); pInsEffDate.SourceColumn = dt.Columns[2].ColumnName; OracleParameter pInsValue = new OracleParameter("pInsValue", OracleDbType.Double); pInsValue.SourceColumn = dt.Columns[1].ColumnName; oraAdapter.UpdateCommand.Parameters.Add(pUpdItem); oraAdapter.UpdateCommand.Parameters.Add(pUpdEffDate); oraAdapter.UpdateCommand.Parameters.Add(pUpdValue); oraAdapter.InsertCommand.Parameters.Add(pInsItem); oraAdapter.InsertCommand.Parameters.Add(pInsEffDate); oraAdapter.InsertCommand.Parameters.Add(pInsValue); oraAdapter.Update(dt); } } } 

当我运行这个时,我得到一个错误,我无法在定义为键的列中插入null。 在数据表中,它们都不是null。 我错过了告诉它数据在哪里但不确定它是什么的东西。 还想知道这是否是做这种事情的正确方法。 我想避免

loop through datatable select to see if record is in oracle table if in table update else insert

因为记录的数量可能是几十万,并且不确定性能会是什么样的。

您是否正在初始化传入的DataTable对象的ColumnName属性? 如果没有,他们可能会读为空。

例如

 public static void Main() { Datatable myDataTable = new DataTable(); myDataTable.Columns = new Columns[3]; myDataTable.Columns[0].ColumnName = "Employees"; myDataTable.Columns[1].ColumnName = "Salary"; myDataTable.Columns[2].ColumnName = "Department"; UpdateOrSaveItems(myDataTable); } 

我发现了错误。 我没有在我的一个插入参数上设置源列。 我在pUdpItem上设置了两次源列,而不是为pUdpItem和pInsItem设置它