简体   繁体   English

将数据从一个表复制到另一个数据库中的另一个表

[英]copy data from one table to another table in another database

I have to write a program that will copy data from one table to a similar table in a different database. 我必须编写一个程序,将数据从一个表复制到另一个数据库中的类似表。 This part is fine but I also have some additional requirements. 这部分很好,但我还有其他要求。

It has to be row by row. 它必须逐行。 and after copying one row, i have to somehow make sure/confirm that the row is copied successfully. 复制完一行后,我必须以某种方式确保/确认该行已成功复制。 And after that i need to delete that row from the source table in the source database and step into the next row. 之后,我需要从源数据库的源表中删除该行,然后进入下一行。

Now my question is how would I confirm that the row is copied successfully? 现在我的问题是如何确认行已成功复制? Is there any good way to do that? 有什么好办法吗?

You need to do all the operations in the same transaction to warranty that the data in the source table is only, and always, deleted when it has been copied to the second table. 您需要在同一事务中执行所有操作,以保证将源表中的数据复制到第二张表后,该数据始终是唯一且始终被删除的。

For doing this, you can use a TransactionScope , which look like this: 为此,您可以使用TransactionScope ,如下所示:

using(var ts = New TransactionScope()) { // Do operations here: read source, write copy, delete destination ts.Complete(); using(var ts = New TransactionScope()){//在此处进行操作:读取源,写入副本,删除目标ts.Complete(); } }

See the docs for TransactionScope here . 请在此处查看TransactionScope文档 And take into account these two things: 并考虑以下两件事:

  1. you need to add a reference to System.Transactions assembly in your project 您需要在项目中添加对System.Transactions程序集的引用
  2. you need to start the MSDTC service (Distributed Transaction Coordinator). 您需要启动MSDTC服务(分布式事务处理协调器)。

How it works: if there are no erros in any of the operations (read source, write copy, deelte source) then the tx.Complete(); 工作原理:如果任何操作(读取源,写入副本,删除源)中没有错误,则tx.Complete(); line is executed, which means that all the operations are confirmed. 行被执行,这意味着所有操作都被确认。 If there are any error in any of the operations, when the error happens, the program continues outside of the using block, thus the ts.Complete() is not called, and all the operations which had been done are rolled back. 如果任何操作中有任何错误,则在发生错误时,程序将在using块之外继续执行,因此不会调用ts.Complete() ,并且所有已完成的操作都将回滚。

In general, if you make any DB operation using any technology (classical SqlCommand, EF or whatever), if it doesn't throw an exception it means that the operation went fine. 通常,如果您使用任何技术(经典的SqlCommand,EF或其他任何技术)进行任何DB操作,则如果它没有引发异常,则表示该操作正常。 So you can do something similar to this using try-catch-finally but it can fail on some occassions, for example: what if the program breaks for any unexpected reason? 因此,您可以使用try-catch-finally进行与此类似的操作,但是在某些情况下可能会失败,例如:如果程序由于意外原因而中断,该怎么办? With the TransactionScope , the pending operation will be rolled backed, but with other solutions, probably not. 使用TransactionScope ,将回滚挂起的操作,但是使用其他解决方案,可能不会。

First, if the row is not copied, the command with which you insert it should return an error. 首先,如果未复制该行,则用于插入该行的命令应返回错误。 If it didn't, then the row was copied correctly. 如果没有,则正确复制了该行。

But if you want to be sure, then before inserting the new row to the second database, query the second database with a SELECT WHERE all the values of all columns are exactly as in the current row. 但是,如果要确定,则在将新行插入第二个数据库之前,请使用SELECT WHERE查询第二个数据库,所有列的所有值都与当前行中的值完全相同。 Remember the number of rows returned. 记住返回的行数。

Then copy the new row, and make the same query again. 然后复制新行,并再次进行相同的查询。 Now the number of rows returned should be greater by one. 现在返回的行数应该增加一。

If there cannot be equal rows, then you will probably want that before the copy the number of rows returned be 0 and after, be 1. 如果行数不能相等,那么您可能希望在复制之前将返回的行数设为0,将其返回到1。

If its the same database a simple database transaction will guarantee that the Copy, Confirm, Delete set is executed as a batch. 如果它是相同的数据库,则简单的数据库事务将保证复制,确认,删除集被成批执行。 In normal circumstances the SELECT COUNT check would be unneccessary - if your insert fails, your RDBMS will tell you about it by throwing an exception; 在正常情况下,不需要进行SELECT COUNT检查-如果插入失败,则RDBMS将通过引发异常来告诉您有关信息; however to answer your question - 但是回答您的问题-

Psudocode: Psudocode:

foreach(@ID in listOfIDs)
{
   BEGIN TRANSACTION
   INSERT INTO DESTINATIONTABLE SELECT * FROM SOURCETABLE WHERE ID=@ID
   DECLARE @COUNTSUCCESS INT
   SET @COUNTSUCCESS = (SELECT COUNT(1) FROM DESTINATIONTABLE WHERE ID=@ID)
   IF(@COUNTSUCESS <> 1) 
   BEGIN
      // Throw some kind of exception
      ROLLBACK TRANSACTION
   END
   DELETE FROM SOURCETABLE WHERE ID=@ID
   COMMIT TRANSACTION
}

You can do so by row count method . 您可以通过行计数方法进行操作。 First create an instance of Dataset . 首先创建一个Dataset实例。 It is there in using System.Data; 它在使用System.Data中; .

    DataSet ds = new DataSet();

And

    ds = rpt3.getShowAll();
    int x = ds.Tables[0].Rows.Count;

rpt3 is my class in which getShowAll() is present.Here my method getShowAll() has a procedure that is having the complete table to be copied.Now rpt3是我的类,其中存在getShowAll()。这里我的方法getShowAll()的过程具有要复制的完整表。
write the code for the copying function . 编写复制功能的代码。 Now again count the rows for the next table and compare them .(Note you have to fetch again while counting rows again means 现在再次对下一张表的行进行计数并进行比较。(请注意,再次计数时必须再次获取

     ds = rpt3.getShowAll();

will be used again . 将再次使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM