#c# #sql-server #sqlbulkcopy
Вопрос:
Я использую bulkcopy для передачи данных из одной базы данных в другую. Первая база данных содержит 3 таблицы : Пользователи, Транзакции и Заказы. В таблице «Пользователь» у меня есть столбец идентификатора, который ссылается на таблицу бронирований как идентификатор пользователя, то же самое решение с таблицей «Транзакции», где у меня есть столбец идентификатора бронирования, который содержит идентификаторы из таблицы бронирований. Вторая база данных содержит те же таблицы, но все столбцы с идентификаторами в них имеют тип данных GUID. Это необходимо для изменения всех идентификаторов на идентификаторы GUID. Для копирования данных я использую bulkcopy
static void Main(string[] args) { string connectionString = GetConnectionString(); // Open a sourceConnection to the AdventureWorks database. using (SqlConnection sourceConnection = new SqlConnection(connectionString)) { sourceConnection.Open(); // Perform an initial count on the destination users table. SqlCommand UsersRowCount = new SqlCommand( "SELECT COUNT(*) FROM " "testMigration.dbo.Users", sourceConnection); // Perform an initial count on the destination bookings table. SqlCommand BookingsRowCount = new SqlCommand( "SELECT COUNT(*) FROM " "testMigration.dbo.Bookings", sourceConnection); // Perform an initial count on the destination bookings table. SqlCommand TransactionsRowCount = new SqlCommand( "SELECT COUNT(*) FROM " "testMigration.dbo.Transactions", sourceConnection); //UsersRow count start long UsersCountStart = System.Convert.ToInt32( UsersRowCount.ExecuteScalar()); Console.WriteLine("User starting row count = {0}", UsersCountStart); //BookingsRow count start long BookingsCountStart = System.Convert.ToInt32( BookingsRowCount.ExecuteScalar()); Console.WriteLine("Bookings starting row count = {0}", BookingsCountStart); //TransactionsRow count start long TransactionCountStart = System.Convert.ToInt32( TransactionsRowCount.ExecuteScalar()); Console.WriteLine("Transactions starting row count = {0}", TransactionCountStart); // Get data from the source table as a SqlDataReader. SqlCommand UsersSourceData = new SqlCommand( "SELECT Id, FirsrtName, LastName, Email " "FROM testMigration.dbo.Users;", sourceConnection); SqlCommand TransactionsSourceData = new SqlCommand( "SELECT Id, BookingId, Status, Amount, Currency " "FROM testMigration.dbo.Transactions;", sourceConnection); SqlCommand BookingsSourceData = new SqlCommand( "SELECT Id, UserId, ServiceName, BookingTime, BookingAddress " "FROM testMigration.dbo.Bookings;", sourceConnection); // Open the destination connection. In the real world you would // not use SqlBulkCopy to move data from one table to the other // in the same database. This is for demonstration purposes only. using (SqlConnection destinationConnection = new SqlConnection(connectionString)) { destinationConnection.Open(); // Set up the bulk copy object. // Note that the column positions in the source // data reader match the column positions in // the destination table so there is no need to // map columns. SqlDataReader UserReader = UsersSourceData.ExecuteReader(); using (SqlBulkCopy bulkCopyUsers = new SqlBulkCopy(destinationConnection)) { bulkCopyUsers.DestinationTableName = "migrationResult.dbo.Users"; try { // Write from the source to the destination. bulkCopyUsers.WriteToServer(UserReader); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { UserReader.Close(); } } SqlDataReader BookingsReader = BookingsSourceData.ExecuteReader(); using (SqlBulkCopy bulkCopyBookings = new SqlBulkCopy(destinationConnection)) { bulkCopyBookings.DestinationTableName = "migrationResult.dbo.Bookings"; try { bulkCopyBookings.WriteToServer(BookingsReader); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { BookingsReader.Close(); } } SqlDataReader TransactionsReader = TransactionsSourceData.ExecuteReader(); using (SqlBulkCopy bulkCopyTransactions = new SqlBulkCopy(destinationConnection)) { bulkCopyTransactions.DestinationTableName = "migrationResult.dbo.Transactions"; try { bulkCopyTransactions.WriteToServer(TransactionsReader); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { TransactionsReader.Close(); } } // Perform a final count on the destination // table to see how many rows were added. long UsersCountEnd = System.Convert.ToInt32( UsersRowCount.ExecuteScalar()); long BookingsCountEnd = System.Convert.ToInt32( BookingsRowCount.ExecuteScalar()); long TransactionsCountEnd = System.Convert.ToInt32( TransactionsRowCount.ExecuteScalar()); Console.WriteLine("Ending user row count = {0}", UsersCountEnd); Console.WriteLine("{0} rows were added to users table.", UsersCountEnd - UsersCountStart); Console.WriteLine("Ending bookings row count = {0}", BookingsCountEnd); Console.WriteLine("{0} rows were added to bookings table.", BookingsCountEnd - BookingsCountStart); Console.WriteLine("Ending transactions row = {0}", TransactionsCountEnd); Console.WriteLine("{0} rows were added to transactions table.", TransactionsCountEnd - TransactionCountStart); Console.WriteLine("Press Enter to finish."); Console.ReadLine(); } } }
И это прекрасно работает! Ошибка, которую я получаю, заключается в следующем :
The given value of type Int32 from the data source cannot be converted to type uniqueidentifier of the specified target column
Очевидно, что они не совпадают, но вопрос в том, : Возможно ли вообще копировать данные из одной базы данных в другую без потери данных и связей между таблицами?
Комментарии:
1. Возможно ли вообще копировать данные из одной базы данных в другую без потери данных и связей между таблицами? Да, так и есть. Но вы меняете типы данных первичного и внешнего ключей, так что у вас будет больше работы. Либо на стороне источника, либо на стороне назначения вам нужно будет добавить
uniqueidentifier
столбцы для ваших GUID и соответствующим образом сопоставить их.