2009-10-23 53 views
1

最近,我的任務是創建一個自動ETL過程,通過讀取主映射文件,將數據抽入基於平面文件名的表中。我決定去用SqlBulkCopy,一切似乎都很好。 IDataReader接口被實現爲讀取平面文件,爲一對一數據映射提供的SQL Server的元數據列數,一切正常,直到我運行帶空字符串的文件。 SqlBulkCopy拋出一個異常,聲明「數據源的String類型的給定值不能轉換爲指定目標列的int類型。」故事結尾,它甚至不關心此列的數據庫類型是否爲INT NULL。我知道我可以進一步解釋元數據,爲給定的列提取數據類型,根據提取的信息構建數據集,從平面文件中重新構建數據,併爲我自己提供一個很好的強類型解決方案,可以工作,但是我一個感覺像他的幸福的懶惰傢伙被微軟惡毒割裂,或者如果有人知道我的突然問題的解決方案,我自己的無能。感謝您的時間。SqlBulkCopy拒絕將String.Empty轉換爲INT NULL

List<String> fileNames; 

DateTime startJobTime = DateTime.Now; 

Console.WriteLine("---------------------------------------------"); 
Console.WriteLine("Start Time: " + startJobTime); 
Console.WriteLine("---------------------------------------------"); 

using (SqlConnection sqlCon = new SqlConnection(sqlConnection)) 
{ 
    try 
    { 
     sqlCon.Open(); 
     sqlCon.ChangeDatabase(edwDBName); 

     // Get service information for staging job 
     UnivStage us = GetStagingJobInfo(jobName, sqlCon); 
     us.StartJobTime = startJobTime; 

     // Get a list of file names 
     fileNames = GetFileList(us, args); 

     if (fileNames.Count > 0) 
     { 
       // Truncate Staging Table 
       TruncateStagingTable(us, sqlCon); 
       // Close and dispose of sqlCon2 connection 
       sqlCon.Close(); 

       Console.WriteLine("Processing files: "); 
       foreach (String fileName in fileNames) 
        Console.WriteLine(fileName); 
       Console.WriteLine(); 
      } 
      else 
      { 
       Console.WriteLine("No files to process."); 
       Environment.Exit(0); 
      } 

      // Re-open Sql Connection 
      sqlCon.Open(); 

      sqlCon.ChangeDatabase(stagingDBName); 


      foreach (String filePath in fileNames) 
      { 
       using (SqlTransaction sqlTran = sqlCon.BeginTransaction()) 
       { 
        using (FlatFileReader ffReader = new FlatFileReader(filePath, us.Delimiter)) 
        { 
         using (SqlBulkCopy sqlBulkCopy = 
           new SqlBulkCopy(sqlCon, SqlBulkCopyOptions.Default, sqlTran)) 
         { 
          SqlConnection sqlCon2 = new SqlConnection(sqlConnection); 

          SetColumnList(sqlCon2, us, sqlBulkCopy); 

          sqlBulkCopy.BatchSize = 1000; 
          sqlBulkCopy.DestinationTableName = 
           us.StagingSchemaName + "." + us.StagingTableName; 

          sqlBulkCopy.WriteToServer(ffReader); 

          sqlTran.Commit(); 

          sqlCon2.Close(); 
         } 
        } 
       } 
      } 

      sqlCon.ChangeDatabase(edwDBName); 
      sqlCon.Close(); 

      sqlCon.Open(); 
      SetRowCount(us, sqlCon); 
      sqlCon.Close(); 

      us.EndJobTime = DateTime.Now; 
      sqlCon.Open(); 
      LogStagingProcess(us, sqlCon); 
      sqlCon.Close(); 

      Console.WriteLine(us.ProcessedRowCount + " rows inserted."); 

      Console.WriteLine("---------------------------------------------"); 
      Console.WriteLine("Success! End Time: " + us.EndJobTime); 
      Console.WriteLine("---------------------------------------------"); 

      Console.ReadLine(); 
     } 
     catch (SqlException e) 
     { 
      RenderExceptionMessagesAndExit(e, 
       "Exception have occured during an attempt to utilize SqlBulkCopy\n"); 
     } 
    } 

回答

4

將您的空字符串轉換爲DBNull

+1

謝謝你的迴應。恐怕我不能因爲自己的束縛而陷入困境。 SqlBulkCopy使用的IDataReader接口只能傳遞字符串數組。 – 2009-10-24 19:44:09