【问题标题】:Insert Datatable into Oracle using OracleDataAdapter使用 OracleDataAdapter 将数据表插入 Oracle
【发布时间】:2018-02-20 12:58:26
【问题描述】:

我需要将 DataGridView 中的特定行插入到 Oracle DB 表中。我所做的是为 OracleDataAdapter 设置 InsertCommand,创建一个具有相同列名的新空 DataTable 并用它填充 OracleDataAdapter。然后我遍历 DataGridView 中的行,将所需的行添加到 DataTable,然后调用 da.Update() 方法 - 但它不起作用,我得到 "Value cannot be null.Parameter name:command"同一行出现错误 - da.Fill()...这是我描述的代码:

private OracleDataAdapter da = new OracleDataAdapter();
private void Inicialize_adapter()
{
    OracleConnection conn = new OracleConnection(conn_string);
    conn.Open();

    OracleCommand insert = new OracleCommand("Myschema.InsertToTable", conn);

    insert.Parameters.Add("ID_IN", OracleDbType.Decimal, 4, "ID");
    insert.Parameters.Add("ID_FK_IN", OracleDbType.Decimal, 4, "ID_FK");
    insert.Parameters.Add("SERIAL_IN", OracleDbType.Decimal, 4, "SERIAL_NO");

    da.InsertCommand = insert;
    da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
    conn.Close();
}

我的 ButtonSave_Click 中的代码:

...

Inicialize_adapter();

DataTable dt_Test = new DataTable();
DataColumn dc = new DataColumn("ID", typeof(int));
dt_Test.Columns.Add(dc);

dc = new DataColumn("ID_FK", typeof(int));
dt_Test.Columns.Add(dc);

dc = new DataColumn("SERIAL_NO", typeof(int));
dt_Test.Columns.Add(dc);

var sequence = New_id(1); // this get's me next sequence in DB
int increase_seq = 0;

foreach (DataGridViewRow row in MyDGV.Rows)
{
    if (row.Cells[0].Value == "Added")
    {
       DataRow newRow = dt_Test.NewRow();

       newRow[0] = sequence+increase_seq;
       newRow[1] = 2";
       newRow[2] = row.Cells[1].Value;

       dt_Test.Rows.Add(newRow.ItemArray);
       ++increase_seq;
     }
 }
 //Fill Adapter -error here
 da.Fill(dt_Test);

 da.Update(dt_Test);

  ...

我也尝试过其他选项,例如 Array Binding,但效果不佳,所以我希望它能够以这种方式工作,因为它更简单。有人知道我的代码有什么问题吗?提前感谢您的帮助!

【问题讨论】:

  • 这是你的插入命令? “Myschema.InsertToTable”?
  • @RenatoAfonso,这是数据库中的存储过程,用于插入到一些相关的表中,所以是的。这可能是 DataAdapter.Fill() 和 Command 之间的冲突吗?

标签: c# oracle11g


【解决方案1】:

更新:

首先:要从 DataGridView 中获取选定的行,您可以这样做:

    foreach (DataGridViewRow dr in MyDGV.Rows)
    {
        if (dr.Selected)
        {
            //Add to DataTable
        }
    }

    //Or even easier:

    foreach (DataGridViewRow row in MyDGV.SelectedRows)
    {
        //Add to DataTable
    }

另一部分是da.Fill()/da.Update()。我不确定“Myschema.InsertToTable”是否是一个存储过程(我对此没有太多经验),但我假设它。所以这里有一些关于如何使用存储过程将 DataTable 插入到 Oracle-Database 的想法:OracleDataAdapter

所以现在我希望我做对了,你可以解决你的问题(:

旧答案:

据我所知,您尝试插入的 DataRow 的列数多于您填充的列数(列名:命令),并且您的数据库不接受该 DataColumn 的空值。因此,您可以更改数据库以允许该列上的空值,或者您在插入之前为该列提供一个值:

foreach (DataGridViewRow row in MyDGV.Rows){
if (row.Cells[0].Value == "Added")
{
   DataRow newRow = dt_Test.NewRow();

   newRow[0] = sequence+increase_seq;
   newRow[1] = 2";
   newRow[2] = row.Cells[1].Value;
   newRow["command"] = "someValue";

   dt_Test.Rows.Add(newRow.ItemArray);
   ++increase_seq;
 }

}

您也尝试过使用 DataBinding 吗?在我看来,这应该会让这一切变得容易得多。

编辑:

好吧,那我弄错了。也许您的命令是错误的,但是当我们使用 Databinding 查看它时,它应该可以工作。这是Tutorial

您需要的是一个 DB-Connection、一个 DataAdapter、一个 DataSet 和一个 BindingSource。

您已经获得了 DataAdapter (OracleDataAdapter da) 和 Connection (OracleConnection conn),但您没有正确使用它。

  1. 初始化数据库连接

    OracleConnection conn = new OracleConnection(conn_string);

  2. 初始化数据适配器

    字符串查询 = "SELECT * FROM YourTable"; OracleDataAdapter da = new OracleDataAdapter(Query, conn);

  3. 填充数据集

    数据集 ds; da.Fill(ds, "表名");

  4. 将数据绑定到 BindingSource

    BindingSource bs = new BindingSource(ds, "Tablename");

  5. 现在您可以填充 DataGridView

    DataGridView dgv; dgv.DataSource = bs;

之后,您可以使用数据,在 DataGridView 等中编辑它们。在其中您可以生成 Insertcommands 等并更新数据(更改的数据、新数据,无论您想要什么)。

bs.EndEdit();

OracleCommandBuilder ocb = new OracleCommandBuilder(da);
da.UpdateCommand = ocb.GetUpdateCommand(true);
da.InsertCommand = ocb.GetInsertCommand(true);
da.DeleteCommand = ocb.GetDeleteCommand(true);

da.Update(ds, "Tablename");

这只是一个简短的概述,您需要更详细地查看它,即在执行 da.Update() 之前进行“bs.EndEdit()”很重要,以便进行更改。

希望对你有帮助。

编辑2:

这是一个更好的可视化代码,我也是用 SQLConnection 等制作的(所以可能需要更改一些调用),但它与 Oracle 相同(前段时间做过):

string Query = "SELECT * FROM YourTable"; 
DataSet ds;  
OracleConnection conn;
OracleDataAdapter da; 
BindingSource bs;
DataGridView dgv = new DataGridView();

private void GetDataAndFillDataGridView()
{
    conn = new OracleConnection(conn_string);
    OracleDataAdapter da = new OracleDataAdapter(Query, conn);
    da.Fill(ds, "Tablename");
    bs = new BindingSource(ds, "Tablename");
    dgv.DataSource = bs;
}

private void buttonSave_Click(object sender, EventArgs e)
{
    bs.EndEdit();

    OracleCommandBuilder ocb = new OracleCommandBuilder(da);
    da.UpdateCommand = ocb.GetUpdateCommand(true);
    da.InsertCommand = ocb.GetInsertCommand(true);
    da.DeleteCommand = ocb.GetDeleteCommand(true);

    da.Update(ds, "Tablename");
}

【讨论】:

  • 不,这不是一种情况,仍然是同样的错误,并且我所有的数据库列都允许空值 - 除了第一个 (ID)。数据绑定是什么意思?如您所见,我从 DataGridView 中排除了一些行,只有这些行需要插入到某个表中。可以发个链接试试看吗?
  • 我已经编辑了问题,这是一个错误,我在 da.Fill() 收到错误,而不是 da.Update(),对此感到抱歉....
  • @Lucy82 我在你的问题上看起来好一点,我理解错了,但如果我理解正确(你想将更改的数据保存回数据库并使用 DataGridView)那么数据绑定就是你的事情。我编辑了我的答案。
  • 感谢您的详细回答。但是你可能还没有完全理解我,所以我会先尝试详细说明。正如我有问题的第一句话所说,我不是试图更新我的 DataGridView,而是从中获取一些行并仅将这些特定行插入到我的数据库中的目标表中,这与 DataGrid 源表不同。
  • 这就是为什么我包含了我的 DataGridView 行的循环并创建了一个包含所需数据的新 DataTable。这只是 da.Fill() 不工作的一部分,以使更新工作。除此之外,DataGridView 已经绑定到 BindingSource。但我没有更新 DataGridView 或它的基础数据,因为那只是来自 DB 的视图,需要插入记录的表包含不同的数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
  • 2011-07-07
  • 2012-12-15
  • 2013-06-10
相关资源
最近更新 更多