我需要将DataGridView中的特定行插入Oracle DB表。我所做的是为OracleDataAdapter设置InsertCommand,创建一个具有相同列名的新的空DataTable,并用它填充OracleDataAdapter。然后我循环遍历DataGridView中的行,将所需的行添加到DataTable然后调用da.Update()方法 - 但它不起作用,我得“值不能为null。参数名称:命令”同一行的错误 - 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);
...
我也尝试了其他选项,比如数组绑定,但这并没有产生好的结果,所以我希望我能以这种方式工作,因为它更简单。有人知道我的代码中有什么问题吗?提前感谢您的帮助!!
答案 0 :(得分: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()。我不确定&#34; Myschema.InsertToTable&#34;是一个存储过程(我没有多少经验),但我正在假设它。以下是关于如何使用存储过程将DataTable插入Oracle数据库的一些想法:OracleDataAdapter
所以现在我希望我做对了,你可以解决你的问题(:
旧回答:
据我所知,这似乎是你试图插入一个DataRow,其中列数多于你填充的列数(Column-Name:command),而你的DataBase不接受该DataColumn的空值。因此,您需要更改DataBase以允许该列上的空值,或者在插入之前为该列赋值:
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),但您没有正确使用它。
初始化DB-Connection
OracleConnection conn = new OracleConnection(conn_string);
初始化DataAdapter
string Query =&#34; SELECT * FROM YourTable&#34 ;; OracleDataAdapter da = new OracleDataAdapter(Query,conn);
填充数据集
DataSet ds; da.Fill(ds,&#34; Tablename&#34;);
将数据绑定到BindingSource
BindingSource bs = new BindingSource(ds,&#34; Tablename&#34;);
现在您可以填充DataGridView
DataGridView dgv; dgv.DataSource = bs;
之后,您可以使用Data,在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");
这只是一个简短的概述,您需要更详细地查看它,即制作&#34; bs.EndEdit()&#34;&#34; bs.EndEdit()&#34;在执行da.Update()之前,所以进行了更改。
我希望这会对你有所帮助。
<强> EDIT2:强>
这是一个更好的可查看代码,我也使用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");
}