2010-12-13 3 views
1

Мне нужно перенести данные из одной базы данных в другую. Я выбрал использовать SqlBulkCopy, но есть проблемы с ним, потому что исходная база данных имеет различные параметры сортировки, чем назначения, так что, у меня есть исключение:SqlBulkCopy с разными сопоставлениями

System.InvalidOperationException: The locale id '1049' of the source column 'Id' and the locale id '1033' of the destination column 'Id' do not match. 
    at System.Data.SqlClient.SqlBulkCopy.AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet internalResults) 
    at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternal() 
    at System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServer(Int32 columnCount) 
    at System.Data.SqlClient.SqlBulkCopy.WriteToServer(IDataReader reader) 
    at MigrateToNormalized.DirectMapCommand.Migrate(SqlConnection source, SqlConnection destination, SqlTransaction transaction) in D:\Projects\APS\DTE\MigrateTo 
Normalized\MigrateToNormalized\MigrateToNormalized\DirectMapCommand.cs:line 53 
    at MigrateToNormalized.Program.Main(String[] args) in D:\Projects\APS\DTE\MigrateToNormalized\MigrateToNormalized\MigrateToNormalized\Program.cs:line 32 

Может кто-нибудь сказать мне, как решить эту проблему без прямого использование операторов COLLATE в SQL-запросе? Есть ли простой способ изменить сортировку для всех столбцов в исходной базе данных?

ответ

-1

Вы можете изменить сортировки столбцов в таблице, которую вы используете для sqlbulkcopy.

Для примера

CREATE TABLE T3 ( С1 INT PRIMARY KEY, С2 VARCHAR (50) NULL, то С3 INT NULL, то С4 INT ); GO

ALTER TABLE T3 ALTER COLUMN C2 VARCHAR (50) КОПИЯМ Latin1_General_BIN

+0

Это правда, но у меня много таблиц и много столбцов. Я не хочу менять коллажи для каждого из них вручную. –

+0

Это вообще не отвечает на вопрос. Вы не можете изменить базу данных клиента, чтобы она работала. – billybob

2

Это правильно, что, когда мы используем SqlBulkCopy, некоторое время он дает ошибку, лучший способ отображения столбцов при использовании SqlBulkCopy ,

Мой Privious Код:

SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder("Data Source=ServerName;User Id=userid;Password=****;Initial Catalog=Deepak; Pooling=true; Max pool size=200; Min pool size=0"); 

SqlConnection con = new SqlConnection(cb.ConnectionString); 

     SqlCommand cmd = new SqlCommand("select Name,Class,Section,RollNo from Student", con); 

     con.Open(); 

     SqlDataReader rdr = cmd.ExecuteReader(); 

     SqlBulkCopy sbc = new SqlBulkCopy("Data Source=DestinationServer;User Id=destinationserveruserid;Password=******;Initial Catalog=DeepakTransfer; Pooling=true; Max pool size=200; Min pool size=0"); 

     sbc.DestinationTableName = "StudentTrans"; 


     sbc.WriteToServer(rdr); 


     sbc.Close(); 
     rdr.Close(); 
     con.Close(); 

Кодекс дает мне ошибку как: идентификатор языка «0» столбца источника «RollNo» и идентификатор языка «1033» столбца назначения " Раздел 'не совпадают.

Теперь после сопоставления столбцов мой код работает успешно.

Мой Измененный код:

SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder("Data Source=ServerName;User Id=userid;Password=****;Initial Catalog=Deepak;"); 

     SqlConnection con = new SqlConnection(cb.ConnectionString); 

     SqlCommand cmd = new SqlCommand("select Name,Class,Section,RollNo from Student", con); 

     con.Open(); 

     SqlDataReader rdr = cmd.ExecuteReader(); 


     SqlBulkCopy sbc = new SqlBulkCopy("Data Source=DestinationServer;User Id=destinationserveruserid;Password=******;Initial Catalog=DeepakTransfer;"); 

     sbc.DestinationTableName = "StudentTrans"; 

     sbc.ColumnMappings.Add("Name", "Name"); 
     sbc.ColumnMappings.Add("Class", "Class"); 
     sbc.ColumnMappings.Add("Section", "Section"); 
     sbc.ColumnMappings.Add("RollNo", "RollNo"); 

     sbc.WriteToServer(rdr); 
     sbc.Close(); 
     rdr.Close(); 
     con.Close(); 

Этот код выполняется успешно.

Попробуйте это и наслаждайтесь.

1

Вы можете выбрать столбцы с различными сортировки:

SELECT Foo COLLATE SQL_Latin1_General_CP1_CI_AS AS Bar FROM Baz 

Это будет конвертировать сверку столбца Foo к новому обобщению. В приведенном выше примере столбец Foo преобразован в сопоставление SQL_Latin1_General_CP1_CI_AS и назван как Бар в запросе.

Затем нужно добавить columnmapping для нового колонки для вашей команды bulkcopy:

using (var bulkCopy = new SqlBulkCopy(connection)) 
{ 
    bulkCopy.DestinationTableName = "FooBars"; 
    bulkCopy.ColumnMappings.Add("Bar", "FooBar"); 
    bulkCopy.WriteToServer(reader); 
} 
1

Простое отображение добавление столбца не работает для меня. И я реализовал вставку через SqlBulkCopy и DataTable - это хорошо работает.

private void BulkCopyTable(string sourceConnection, string targetConnection, Table sTable, Table tTable) 
    { 
     using (SqlConnection sourceConn = new SqlConnection(sourceConnection)) 
     { 
      if (cbFixStructure.Checked) 
       CheckAndRecreateTarget(targetConnection, sTable, tTable); 

      string selectSql = "SELECT * FROM " + sTable.Schema + ".[" + sTable.Name + "]"; 

      string selectCntSql = "SELECT COUNT(*) FROM " + sTable.Schema + ".[" + sTable.Name + "] WITH(NOLOCK)"; 
      using (SqlCommand selectCmd = new SqlCommand(selectSql, sourceConn)) 
      { 
       selectCmd.CommandTimeout = 60 * 100 * 1000; 
       sourceConn.Open(); 
       Int64 totalCount = 0; 
       using (SqlCommand cntCommand = new SqlCommand(selectCntSql, sourceConn)) 
       { 
        cntCommand.CommandTimeout = 60 * 100 * 1000; 
        totalCount = Convert.ToInt64(cntCommand.ExecuteScalar()); 
       } 

       DataTable dtBuffer = new DataTable(); 
       var columns = sTable.Columns.Cast<Column>().Where(p => p.Computed == false).ToList(); 
       foreach (var clm in columns) 
       { 

        var sdt = clm.DataType.SqlDataType; 
        if (sdt == SqlDataType.UserDefinedDataType) 
        { 
         var lst = Enum.GetValues(typeof(SqlDataType)).Cast<SqlDataType>(); 
         sdt = lst.Where(p => p.ToString().ToLower() == TargetDataBase.UserDefinedDataTypes[clm.DataType.Name].SystemType.ToString()).First(); 
        } 


        dtBuffer.Columns.Add(new DataColumn(clm.Name, GetClrType(sdt))); 
       } 
       using (SqlDataReader reader = selectCmd.ExecuteReader()) 
       { 

        using (SqlBulkCopy blkCopy = new SqlBulkCopy(targetConnection, SqlBulkCopyOptions.KeepIdentity)) 
        { 
         blkCopy.BulkCopyTimeout = 60 * 100 * 1000; 
         blkCopy.DestinationTableName = sTable.Schema + ".[" + sTable.Name + "]"; 


         foreach (var colmn in columns) 
         { 
          blkCopy.ColumnMappings.Add(colmn.Name, colmn.Name); 
         } 


         int bufferCountLengthMax = 500; 
         int rowCnt = 0; 
         int globalCounter = 0; 
         while (reader.Read()) 
         { 
          var dataRow = dtBuffer.NewRow(); 
          foreach (var clm in columns) 
          { 
           dataRow[clm.Name] = reader[clm.Name]; 
          } 
          dtBuffer.Rows.Add(dataRow); 
          rowCnt++; 
          globalCounter++; 
          if (rowCnt >= bufferCountLengthMax) 
          { 
           dtBuffer.AcceptChanges(); 
           blkCopy.WriteToServer(dtBuffer); 
           rowCnt = 0; 
           dtBuffer.Rows.Clear(); 
           GC.Collect(); 
           DoLogText(String.Format("Table \"{0}\" copied rows {1} out of {2}", sTable.Schema + ".[" + sTable.Name + "]", globalCounter, totalCount)); 
          } 
         } 
         if (rowCnt > 0) 
         { 
          dtBuffer.AcceptChanges(); 
          blkCopy.WriteToServer(dtBuffer); 
          rowCnt = 0; 
          dtBuffer.Rows.Clear(); 
          GC.Collect(); 
          DoLogText(String.Format("Table \"{0}\" copied rows {1} out of {2}", sTable.Schema + ".[" + sTable.Name + "]", globalCounter, totalCount)); 
         } 

        } 
       } 
      } 

     } 
     DoLogText(String.Format("Table \"{0}\" done", sTable.Name)); 
    } 
+0

Это не отвечает на вопрос. Если у вас есть другой вопрос, вы можете задать его, нажав [Ask Question] (http://stackoverflow.com/questions/ask). Вы также можете [добавить щедрость] (http://stackoverflow.com/help/privileges/set-bounties), чтобы привлечь больше внимания к этому вопросу, как только у вас будет достаточно [репутации] (http://stackoverflow.com/help/ Что-репутация). - [Из обзора] (/ review/low-quality-posts/11508752) – APH

+0

Да, это обходной путь, тот, который действительно работает :). Я потратил время на другие решения, размещенные здесь, но ни один из них не работает. – user2932688

Смежные вопросы