2010-12-13 101 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 

谁能告诉我,如何解决没有直接这个问题在SQL查询中使用COLLATE语句?是否有一些简单的方法可以更改源数据库中所有列的排序规则?

回答

-1

您可以更改您用于sqlbulkcopy的表中列的排序规则。

对于实施例

CREATE TABLE T3 ( C1 INT PRIMARY KEY, C2 VARCHAR(50)NULL, C3 INT NULL, C4 INT ); GO

ALTER TABLE T3 ALTER COLUMN C2 VARCHAR(50)COLLATE Latin1_General_BIN

+0

这是真的,但我有很多的表和很多列。我不想手动更改他们每个人的通风。 – 2010-12-13 18:42:15

+0

这完全没有回答这个问题。您无法更改客户端数据库以使其正常工作。 – billybob 2017-11-16 22:32:54

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(); 

的代码是给我的错误是: 源列“RollNo”和目标列“的区域设置ID“1033”的区域设置ID“0”部分'不匹配。

列映射后我的代码正在运行成功。

我修改的代码是:

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列被转换为排序规则SQL_Latin1_General_CP1_CI_AS,并在查询中命名为Bar

然后您需要添加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

这并没有真正回答这个问题。如果您有不同的问题,可以通过单击[提问](http://stackoverflow.com/questions/ask)来提问。您还可以[添加赏金](http://stackoverflow.com/help/privileges/set-bounties)在您拥有足够的[声誉](http://stackoverflow.com/help/)时吸引更多人关注此问题什么声誉)。 - [来自评论](/评论/低质量帖/ 11508752) – APH 2016-03-05 04:30:41

+0

是的,这是解决方法,真正有效的:)。我花时间在这里发布的其他解决方案,但没有一个是可行的。 – user2932688 2016-03-07 16:24:16