通过OleDbDataAdapter.Update将任意值插入AutoNumber字段

时间:2016-09-01 22:12:49

标签: c# database ms-access insert

我的Access数据库中有一个这样的表

id  name    address     date
1   first   addresss    5/6/2005 9:17:52 AM
2   test1   address1    5/11/2005 5:23:32 AM
3   test22  address2    5/11/2006 5:23:32 AM
8   test3   address3    5/11/2007 5:23:32 AM
9   test4   address4    5/11/2008 5:23:32 AM
13  test    address     5/11/2008 5:23:32 AM

此处,id提交的是Primary Key - AutoNumber字段。现在,如何使用C#将ID 11 的记录插入此表?

当我尝试id低于13或高于14的插入时,下一个插入的值将是14.如果我想将已删除的记录插回到表中会怎样?

任何解决此问题的解决方法或实际解决方案都将受到赞赏。

修改1:

很高兴听到可以将值插入AutoNumber字段。这是我用来进行批量插入的功能。 DataTable具有相同的列名,具有相似的数据类型。但是,如上所述,代码可以自动分配主键。

这个特定代码可能有任何修复方法吗?

public void AccessBulkCopy(DataTable table)
{
    foreach (DataRow r in table.Rows)
        r.SetAdded();

    var myAdapter = new OleDbDataAdapter("SELECT * FROM " + table.TableName, _myAccessConn);

    var cbr = new OleDbCommandBuilder(myAdapter);
    cbr.QuotePrefix = "[";
    cbr.QuoteSuffix = "]";
    cbr.GetInsertCommand(true);

    myAdapter.Update(table);
}

2 个答案:

答案 0 :(得分:2)

Access数据库引擎确实确实允许我们使用SQL将任意值插入自动编号字段。以下内容适用于您的情况,前提是表中已经有一行[id] = 11:

string sql = "INSERT INTO [YourTable] ([id], [name]) VALUES (?,?)";
using (var cmd = new OdbcCommand(sql, conn))
{
    cmd.Parameters.AddWithValue("?", 11);
    cmd.Parameters.AddWithValue("?", "Gord");
    cmd.ExecuteNonQuery();
}

修改

使用OleDbDataAdapterInsertCommand自动生成的OleDbCommandBuilder会识别[id]是一个自动编号列,并从CommandText("INSERT INTO ...")中省略它。所以," id"您的DataTable中的列被忽略,您获得了自动分配的[ID]值。

如果您希望INSERT中包含[id]列,那么您需要创建自己的OleDbDataAdapter.InsertCommand,如下所示:

using (var da = new OleDbDataAdapter("SELECT [id], [name] FROM [YourTable] WHERE 1=0", conn))
{
    DataTable dt = new DataTable();
    da.Fill(dt);

    var cmd = new OleDbCommand("INSERT INTO [YourTable] ([id], [name]) VALUES (?,?)", conn);
    cmd.Parameters.Add(new OleDbParameter("?", OleDbType.Integer, 0, "id"));
    cmd.Parameters.Add(new OleDbParameter("?", OleDbType.VarWChar, 255, "name"));
    da.InsertCommand = cmd;

    DataRow dr = dt.NewRow();
    dr["id"] = 11;
    dr["name"] = "Gord";
    dt.Rows.Add(dr);
    da.Update(dt);
}

答案 1 :(得分:0)

你不应该。不应编辑或更改MS Access中的自动编号主键字段。即使你发现它周围的黑客,这是不好的做法。某些SQL数据库具有允许它的变通方法。

通常我们所做的就是永远不要删除表格。相反,有一个字段,也许是一个文本字段,可能是一个字符,表示A表示活动,D表示删除。

然后设置一个视图(查询),它返回所有字段,但只返回活动行。然后,您可以在该视图上执行所有报表,表单,查询和工作。

当您需要重新插入已删除的行时,您会有一个特殊的更新,将已删除的状态更改回活动状态。