2009-11-20 104 views
1

我想在C#中设置一个同步例程将数据从一个MS访问数据库发送到一个SQL服务器。 MS Access不是我的选择,它只是它的方式。C#同步MS Access数据库到SQL服务器

我能够查询MS Access数据库并获取OleDbDataReader记录集。我可能会读取每个单独的记录并将其插入SQL Server,但看起来很浪费。

有没有更好的方法来做到这一点。我知道我可以在MS Access中链接到sql server并执行更新,但这是为了最终用户,我不希望他们搞乱访问。

编辑: 只看SqlBulkCopy的我认为这可能是答案,如果我让我的成绩进入的DataRow []

回答

7

我发现了一个.NET解决方案,我很满意。它允许我将程序的访问权限授予任何用户。它涉及SQLBulkCopy类。

private static void BulkCopyAccessToSQLServer 
     (CommandType commandType, string sql, string destinationTable) 
    { 
     using (DataTable dt = new DataTable()) 
     { 
      using (OleDbConnection conn = new OleDbConnection(Settings.Default.CurriculumConnectionString)) 
      using (OleDbCommand cmd = new OleDbCommand(sql, conn)) 
      using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd)) 
      { 
       cmd.CommandType = commandType; 
       cmd.Connection.Open(); 
       adapter.SelectCommand.CommandTimeout = 240; 
       adapter.Fill(dt); 
       adapter.Dispose(); 
      } 

      using (SqlConnection conn2 = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString)) 
      { 
       conn2.Open(); 
       using (SqlBulkCopy copy = new SqlBulkCopy(conn2)) 
       { 
        copy.DestinationTableName = destinationTable; 
        copy.BatchSize = 1000; 
        copy.BulkCopyTimeout = 240; 
        copy.WriteToServer(dt); 
        copy.NotifyAfter = 1000; 
       } 
      } 
     } 
    } 

基本上这使从MS Access数据到一个DataTable然后它使用第二连接CONN2和SqlBulkCopy类从该数据表到SQL Server发送数据。这可能不是最好的代码,但应该给任何读这个想法的人。

+0

这是一个耻辱,有0 upvotes,因为这是完美的。我只需要更改连接字符串以使用2010年的Access数据库accdb文件的ACE 12格式和一切工作。谢谢! – chrismay 2011-09-18 15:11:55

1

你应该利用在RBAR努力SET基于查询的力量。

查看SSIS解决方案以同步数据,然后使用SQL Server代理程序定期运行包以定期运行。

你可以从命令行调用一个SSIS包,这样你就可以有效地从MS Access或C#中执行它。

此外,SQL Server,MS Access数据库和SSIS包不必位于同一台计算机上。只要您的调用程序可以看到SSIS包,并且该包可以连接到SQL Server和MS Access DB,则可以将数据从一个地方传输到另一个地方。

这听起来像你在做什么是ETL。有几种工具可以完成这一工作,对我来说,没有什么理由重新发明功能。你有SQL Server,因此你有SSIS。它有很多工具可用于自动转换,清理,查找等,您可以直接使用这些工具。

除非这是一个真正的剪切干燥数据加载,并且上传的复杂度绝对没有余地增加(是的,正确!),我会使用经过验证和测试的ETL工具。

+0

想到了这一点,但我需要它作为和当时的操作不是预定的。此外,SQL Server的需要SQL服务器和MS访问数据库与我记得在同一台服务器上。 – PeteT 2009-11-20 14:35:33

+0

回答编辑意见 – 2009-11-20 14:52:42

0

如果SQL Server Integration Services不是一个选项,您可以将临时文本文件写出您从Access读取的数据,然后调用bcp.exe将其加载到数据库。

0

我以前做过这样的事情。

我用

OleDbConnection aConnection = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", fileName)); 
      aConnection.Open(); 

打开Access数据库。然后

OleDbCommand aCommand = new OleDbCommand(String.Format("select * from {0}", accessTable), aConnection); 
        OleDbDataReader aReader = aCommand.ExecuteReader(); 

执行从表中读取。然后

int fieldCount = aReader.FieldCount; 

获取字段数

while (aReader.Read()) 

循环记录和

object[] values = new object[fieldCount]; 
         aReader.GetValues(values); 

检索值。

+0

我没有问题获取数据。我可以将它读入数据读取器或数据表,只是不知道如何从每个记录插入到SQL Server。 – PeteT 2009-11-20 14:37:39

+0

你可以做的是建立一个“;”定界插入语句的字符串。你可以决定一个好的数字,比如说10,100或1000.循环记录直到达到这个限制,然后执行一条语句来执行一个多重插入。这将减少数据库执行的次数。 – 2009-11-20 14:46:52

+0

是一个好主意,仍然希望有人有我明显错过,使其简单。 – PeteT 2009-11-20 14:48:48

-1

在同步完成后,您不能将Access文件传输到服务器并将其删除吗? 你可以创建Windows服务..

0

有几种方法可以同步,但是当您在sql server中更改字段名称或添加新列或删除时,可能会出现问题。最好的选择是:

  1. 为sql server和oledb创建连接。

  2. 编写自定义查询以从一个连接中获取记录并将其保存到另一个连接。

  3. 在执行之前,请确保以更新所有表定义的方式进行编程。

在我的情况下,这种方式有所帮助,因为sql server上的负载降低了。