如何使用insert语句将数百万个不同RDBMS的数据插入到SQL Server数据库中?

时间:2017-12-14 13:12:55

标签: c# mysql database ado.net

我的SQL Server中有两个数据库,每个数据库包含一个目前的单个表。

我有2个数据库,如下所示:

1)Db1(MySQL)

2)Db2(Oracle)

现在我要做的是用MySQL中的Db1数据填充SQL Server db1的数据库表,如下所示:

Insert into Table1 select * from Table1
  

从Table1中选择*(Mysql Db1) - 来自Mysql数据库的数据

     

插入Table1(Sql server Db1) - 插入来自Mysql的数据   考虑相同模式的数据库

我不想使用sqlbulk副本,因为我不想通过块数据插入块。我想在1中插入所有数据,考虑数百万个数据,因为我的操作不仅限于在数据库中插入记录。因此,用户必须等待很长时间,比如数百万的数据在数据库中按块插入块,然后再次进行我的进一步操作,这也是长时间运行的操作。

因此,如果我将此进程加速,那么考虑到所有记录都在我的本地sql server实例中,我可以加快第二次操作。

这可以在C#应用程序中实现吗?

更新我研究了关于链接服务器 @GorDon Linoff 建议我链接服务器可以用来实现这个场景但是基于我的研究似乎我不能通过代码创建链接服务器。

我想在 ado.net 的帮助下完成这项工作。

这正是我要做的事情:

考虑我有2个不同的客户端RDBMS,其中包含2个数据库和客户端内部的一些表。

所以数据库是这样的:

Sql Server :

Db1

Order
Id      Amount
1       100
2       200
3       300
4       400


Mysql or Oracle :

Db1:

Order
Id      Amount
1       1000
2       2000
3       3000
4       400

现在我想比较从源(SQL Server)到目标数据库(MySQL或Oracle)的Amount列。

我将使用这两个不同的RDBMS数据库表来比较Amount列。

在C#中,我可以做的就像在数据表(在内存中)中的块记录获取块,然后在代码的帮助下比较这些记录,但考虑到数百万条记录需要花费很多时间

所以我想做一些比这更好的事情。

因此我认为我在2个数据库中的本地SQL服务器实例中显示了这2个RDBMS记录,然后创建了基于Id加入这2个表的连接查询,然后利用DBMS处理能力,可以比较数百万个有效记录。

这样的查询有效地比较了数百万条记录:

select SqlServer.Id,Mysql.Id,SqlServer.Amount,Mysql.Amount from SqlServerDb.dbo.Order as SqlServer
Left join MysqlDb.dbo.Order as Mysql on SqlServer.Id=Mysql.Id
where SqlServer.Amount != Mysql.Amount

当我在本地服务器实例中使用数据库:SqlServerDb和MysqlDb这两个不同的RDBMS数据时,上面的查询有效,这将获取数量不匹配的记录:

所以我试图将这些记录从源(Sql server Db)获取到其Amount列值不匹配的MySQL。

预期输出:

Id      Amount
1       1000
2       2000
3       3000

那么有什么方法可以实现这种情况吗?

6 个答案:

答案 0 :(得分:3)

SELECT侧,使用.csv

创建SELECT ... INTO OUTFILE ...文件(制表符分隔)

INSERT方面,使用LOAD DATA INFILE ...(或目标机器的语法)。

一次完成所有操作可能比分块更容易编码,并且可能(或可能不)更快地运行。

答案 1 :(得分:2)

SqlBulkCopy可以接受DataTableSystem.Data.IDataReader作为输入。

使用您的查询来读取源数据库,在源MySQL或Oracle DB上设置ADO.Net DataReader,并将读者传递给WriteToServer()的{​​{1}}方法。

这可以无限制地复制几乎任意数量的行。我使用数据读取器方法复制了数亿行。

答案 2 :(得分:1)

如何在远程数据库中添加更改日期。

然后你可以得到自上次同步以来已经改变的所有行,只是比较那些?

答案 3 :(得分:1)

首先不要使用链接服务器。它很诱人,但它会带来更多的麻烦。像更新和插入一样,将获取所有目标数据库到源数据库并插入/更新并发布所有数据以回溯目标。

据我所知,您正在尝试将已更改的数据复制到目标系统中。

我建议在源表上使用timestamp列。如果源表上的任何更改时间戳列由sql server更新。

在目标上,获取最大ID和最大时间戳。最多两个查询

在源上,source.ID <= target.MaxID && source.timestamp >= target.MaxTimeTamp为真的行是上次同步后需要更新的行。 source.ID > target.MaxID为真的行是上次同步后插入的行。

现在你不必比较两个世界,你只需要获得所有更新和插入。

答案 4 :(得分:1)

您需要使用ODBC和正确的驱动程序创建链接服务器连接,之后您可以使用openquery执行查询。

看一下openquery:

https://msdn.microsoft.com/en-us/library/ms188427(v=sql.120).aspx

答案 5 :(得分:1)

是的,SQL Server在处理集合时非常有效,所以让我们继续使用它。

简而言之,我投球的是

  1. 将数据从源加载到目标数据库上的登台表(登台表=表,暂时保存源表中的原始数据,与源表相同的结构...添加跟踪列以进行品味)。这将由您的C#代码完成...从source_table选择DataTable,然后从SqlBulkCopy选择到临时表。

  2. 在目标数据库上有一个存储过程,用于协调目标表和登台表之间的数据。您的C#代码调用存储过程。

  3. 鉴于您正在谈论数百万行,另一件可以使事情变得更快的事情是在插入表之前删除登台表上的索引并在插入之后和执行任何选择之前重新创建索引。