【问题标题】:Using a Data Table, how do I check if the data matches an entry in an Access database and adds the content?使用数据表,如何检查数据是否与 Access 数据库中的条目匹配并添加内容?
【发布时间】:2016-12-01 07:52:25
【问题描述】:

使用此代码,我从 Excel 文档中创建了一个数据表。数据集也显示在 datagridview 中。

                OleDbcon.Open();                  
                tbContainer = new SD.DataTable();
                OleDbCommand cmd = new OleDbCommand();
                System.Data.DataTable dt = new System.Data.DataTable();
                OleDbDataAdapter oda = new OleDbDataAdapter(string.Format("select * from [{0}$]", sheetName), OleDbcon);
                DataSet ds = new DataSet();
                oda.Fill(ds);
                DGVExcel.DataSource = ds.Tables[0];
                Console.WriteLine(dt.Rows.Count);
                OleDbcon.Close();

现在我有了这个 Dataset/DataTable,我希望能够将其数据与已经建立的访问数据库的内容相匹配,然后添加相关值。

比如说我在数据库中有这个:

姓名 ||手指 ||大拇指 ||身份证

罗斯 || 10 || 2 || 12

老板 || 9 || 1 || 14

excel文件恰好有完全相同的数据,除了用于识别唯一条目的ID之外,其他字段都会被添加。

所以罗斯的值变成了 20||4,Boss 变成了 18 || 2.

如何使用我刚刚创建的DataSet/DataTable来执行这个操作?

我想到的想法是使用“如果不存在”Select * from Table where ID = [?]。但我不知道如何设置ID。 for循环会起作用吗?伪代码:

for (int i = 2; i < DB.Count ; i++){
  string query = "if not exists Select * from Table where ID = " + DGridView.Rows[i].Cells[LastCell];

我之前被推荐过 Linq,但老实说我不知道​​从哪里开始。

编辑 x2:

========================================

所以我认为我一直在以错误的方式解决这个问题,无论如何,我设法将我的 excel 数据直接插入 Access 表中,而无需求助于数据集/原始查询。唯一需要注意的是,表结构需要与访问表完全匹配,尽管我认为无论如何总是如此。

代码:

                    conn.Open();
                    string sqls = @"INSERT INTO ACXL SELECT * FROM [Excel 12.0;HDR=YES;DATABASE=" + openFileDialog.FileName + "].[" + txtSheetName.Text + "$];";
                    OleDbCommand cmd = new OleDbCommand();
                    cmd.Connection = conn;
                    cmd.CommandText = sqls;
                    cmd.ExecuteNonQuery();
                    conn.Close();

关于SQL表匹配!

【问题讨论】:

  • 根据您的描述,我相信您可以推断出 Name 的自然键,因此只需更改您的 if not exists select 以使用它而不是 ID。
  • 最好的方法之一是将其传递给 SQL 存储过程,该过程完成合并语句,该语句可以插入、更新和删除(如果需要)表中的任何记录符合您的条件
  • @JohnWu,我不确定这是否会发生很大变化。我遇到的问题是如何保持索引相对于表和数据库内容。所以,它可以是任意数量的 ID 或该数字的名称,我猜一个名称可能有重复的值,因此 ID 字段是我用来参考的。
  • @SimonPrice,我正在使用 MS Access 数据库。我不认为它能够使用存储过程?我之前用过SQL触发器,原理是一样的吗?
  • 哦,我的错...抱歉,您认为您正在使用 SQL 数据库,好的,那么在这种情况下 LINQ 是您最好的朋友,建议您购买并阅读此microsoftpressstore.com/store/…

标签: c# linq ms-access datagridview datatable


【解决方案1】:

我会这样做。

  1. 在 Access 中创建一个“工作表”,其中包含与主表相同的列定义,但 ID 列应为 int 而不是标识,以便您可以手动向其中插入值。

  2. 在工作表中插入行,在 Excel 电子表格中每行插入一行。为此,您可以使用 for...each 遍历数据集并为每一行执行 INSERT 语句。

  3. 执行单个 UPDATE 语句,将工作表连接到主表并根据需要对字段求和。通过在单个语句中执行此操作,您可以避免在逐行执行更新并且中途失败时发生的棘手情况。

  4. 截断工作表。

为了将行插入到临时表中,我可能会写这样的东西。请注意,您不需要传递Name,因为它完全依赖于ID。这简化了事情——如果你通过了它,你也必须逃避它。

void InsertRowIntoTempTable(int id, int fingers, int thumbs)
{
    using (var conn = this.GetDatabaseConnection())
    {
        var cmd = new SqlCommand(conn);
        cmd.CommandText = String.Format("INSERT INTO TempTable VALUES ({0},{1},{2})", id, fingers, thumbs);
        conn.Open();
        cmd.ExecuteNonQuery();
    }
}

void InsertRowsIntoTempTable(DataTable source)
{
    for each (var row in source.Rows)
    {
        InsertRowIntoTempTable(row["ID"], row["Fingers"], row["Thumbs"]);
    }
}

【讨论】:

  • 我很快就会尝试制作一个工作样本。那么,我想要的是一个内部连接,对吗?因为我真的不想要这些空值,它只需要添加匹配的值。 Update ACTB VALUES Fingers, Thumbs from Excel INNER JOIN ACTB on Excel.PersonID == ACTB.PersonIDselect Excel.*,ACTB.* from Excel,ACTB where Excel.PersonID = ACTB.PersonID;
  • 关注this pattern
  • 我尝试了您的编辑,但它抛出了一个错误:无法从您的 foreach 将类型对象转换为 int(source.Rows 中的 var 行)。或者类型对象不可分配给类型“int”。与此同时,我会尝试让上面的 foreach 工作。
  • 我设法简单地将 Excel 数据直接插入 Access 数据库,而无需数据集/表中间人。请参阅我对代码的编辑,但这有点太简单了。我将继续创建查询原型。
猜你喜欢
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 2014-08-08
  • 2015-04-25
  • 1970-01-01
  • 2013-05-23
  • 2020-12-03
  • 2018-03-30
相关资源
最近更新 更多