2010-12-13 4 views
1

한 데이터베이스에서 다른 데이터베이스로 데이터를 마이그레이션해야합니다. 나는 예외가있어, SqlBulkCopy의를 사용하지만, 소스 데이터베이스가 목적지와 다른 데이터 정렬을 가지고 있기 때문에, 그것으로 문제가있는 choosed 할, 그래서 :다른 데이터 정렬을 사용하는 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에 대해 사용중인 테이블의 열에 대한 데이터 정렬을 변경할 수 있습니다. 예

표 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

사실,하지만 테이블이 많고 많은 열이 있습니다. 나는 그들 각각에 대해 콜레 션을 변경하고 싶지 않다. –

+0

이 질문에 전혀 대답하지 않습니다. 클라이언트 데이터베이스를 변경하여 작동하지 못하게 할 수 있습니다. – billybob

2

그것은 바로입니다 우리는 SqlBulkCopy의, 그것은 오류, 당신은 SqlBulkCopy의를 사용하는 경우 열을 매핑 할 수있는 가장 좋은 방법을 제공 시간을 사용할 때 .

내 Privious 코드 : 로케일 ID '0'원본 열 'RollNo'및 대상 컬럼 '의 로케일 ID'1033 '의를 : 코드는 다음과 같이 나에게 오류를주고 있었다

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

섹션 '이 일치하지 않습니다.

이제 열 매핑 후 내 코드가 성공적으로 실행됩니다.

내 수정 된 코드는 다음과 같습니다이 코드는 성공적으로 실행

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 추가해야합니다

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

+0

그래, 해결 방법은 정말 작동합니다 :). 여기에 게시 된 다른 솔루션에 대한 시간을 보냈지 만 그 중 어느 것도 실행 가능하지 않습니다. – user2932688

관련 문제