【问题标题】:Transferring data between two Access databases在两个 Access 数据库之间传输数据
【发布时间】:2013-10-16 22:59:19
【问题描述】:

我正在编写一个简单的报告工具,它需要将数据从一个 Access 数据库中的表移动到另一个 Access 数据库中的表(表结构相同)。但是,我是 C# 新手,很难找到可靠的解决方案。

任何指针将不胜感激。

【问题讨论】:

  • 愚蠢的问题,但表实际上是访问表吗?很多人使用 Access 作为前端与另一个数据库提供程序(SQL、MySQL 等)来存储实际数据,你的问题的答案会有所不同,这就是我问的原因!

标签: c# ms-access


【解决方案1】:

Access SQL 支持使用 IN 子句来指定表驻留在不同的数据库中。以下 C# 代码从 Database1.accdb 中名为 [YourTable] 的表中选择行并将它们插入到 Database2.accdb 中名为 [YourTable](具有相同结构)的现有表中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;

namespace oleDbTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string myConnectionString;
            myConnectionString =
                    @"Provider=Microsoft.ACE.OLEDB.12.0;" +
                    @"Data Source=C:\Users\Public\Database1.accdb;";

            using (var con = new OleDbConnection())
            {
                con.ConnectionString = myConnectionString;
                con.Open();

                using (var cmd = new OleDbCommand())
                {
                    cmd.Connection = con;
                    cmd.CommandType = System.Data.CommandType.Text;
                    cmd.CommandText =
                        @"INSERT INTO YourTable IN 'C:\Users\Public\Database2.accdb' " +
                        @"SELECT * FROM YourTable WHERE ID < 103";
                    cmd.ExecuteNonQuery();
                }
                con.Close();
            }
            Console.WriteLine("Done.");
        }
    }
}

【讨论】:

  • 只是好奇:为什么有些人选择以 ....*冗长*的方式编写代码?我的意思是,OleDbConnection 有一个接受数据库连接字符串的重载,OleDbCommand 有一个接受 SQL 文本和OleDbConnection 的重载。有好处吗?我的开发环境中有双显示器、小字体和分屏;然而,我仍然无法在屏幕上一次看到所有我想看到的代码。
  • @jp2code 在我看来,以这种方式编写示例代码的主要好处是它是明确的。刚开始使用给定语言或工具的人不必熟悉特定的重载,也不必在实例化对象时推断(或猜测)正在初始化的内容。就我而言,我还有一个用于测试的通用 C# 控制台应用程序(“oleDbTest”),有时我会复制并粘贴几个不同的变量分配(例如,myConnectionString);然后我在这里发布代码时删除所有额外的。
  • 将此类字符串存储在变量中还可以方便地检查它们以进行调试。调试简单胜过简洁。
【解决方案2】:

很多方法。

0) 如果只有一次,复制并粘贴表格。

1) 如果您想在 Access 中执行此操作,最简单的方法是在新数据库中创建链接表,然后在新数据库中创建表查询。

2) 您可以直接引用第二个表。 选择 * FROM TableInDbX IN 'C:\SomeFolder\DB X';

3) 在宏中,您可以使用 DoCmd 对象的 TransferDatabase 方法链接相关表,然后运行适当的追加和更新查询以进行同步。

4) VBA http://www.techonthenet.com/access/questions/new_mdb.php

【讨论】:

  • 欢迎来到 *!
【解决方案3】:

给定列名 Col1Col2Col3

private static void Migrate(string dbConn1, string dbConn2) {
  // DataTable to store your info into
  var table = new DataTable();
  // Modify your SELECT command as needed
  string sqlSelect = "SELECT Col1, Col2, Col3 FROM aTableInOneAccessDatabase ";
  // Notice this uses the connection string to DB1
  using (var cmd = new OleDbCommand(sqlSelect, new OleDbConnection(dbConn1))) {
    cmd.Connection.Open();
    table.Load(cmd.ExecuteReader());
    cmd.Connection.Close();
  }
  // Modify your INSERT command as needed
  string sqlInsert = "INSERT INTO aTableInAnotherAccessDatabase " +
    "(Col1, Col2, Col3) VALUES (@Col1, @Col2, @Col3) ";
  // Notice this uses the connection string to DB2
  using (var cmd = new OleDbCommand(sqlInsert, new OleDbConnection(dbConn2))) {
    // Modify these database parameters to match the signatures in the new table
    cmd.Parameters.Add("@Col1", DbType.Int32);
    cmd.Parameters.Add("@Col2", DbType.String, 50);
    cmd.Parameters.Add("@Col3", DbType.DateTime);
    cmd.Connection.Open();
    foreach (DataRow row in table.Rows) {
      // Fill in each parameter with data from your table's row
      cmd.Parameters["@Col1"].Value = row["Col1"];
      cmd.Parameters["@Col2"].Value = row["Col2"];
      cmd.Parameters["@Col3"].Value = row["Col3"];
      // Insert that data
      cmd.ExecuteNonQuery();
    }
    cmd.Connection.Close();
  }
}

现在,我不经常使用 Access 数据库,因此您可能需要在那里进行一些调整。

不过,这应该会让你顺利上路。

值得注意的是:

如果我没记错的话,Access 不会注意您的 OleDbParameter 名称!您可以随意调用它们,实际上大多数人只是在参数字段中使用问号?

因此,您必须按照语句调用它们的顺序添加和更新这些参数。

那么,为什么我将参数命名为@Col1@Col2@Col3?在这里,它只是为了帮助您和我了解每个参数要映射到的位置。进入也是一个好习惯。如果您曾经迁移到更好的数据库,希望它会注意参数的名称。

【讨论】:

  • 感谢大家的出色帮助 - 真的非常感谢(而且很有趣)。一切顺利。