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

相關問題