2010-03-25 17 views
4

我有一個CSV從另一個DB看起來像這樣(ID,姓名,備註)轉儲:如何從CSV中批量插入一些字段具有換行符時?

1001,John Smith,15 Main Street
1002,Jane Smith,"2010 Rockliffe Dr.
Pleasantville, IL
USA"
1003,Bill Karr,2820 West Ave.

最後一個字段可以包含回車和逗號,在這種情況下,它是由雙引號包圍。我需要保留這些回報和逗號。

我使用此代碼導入CSV到我的表:

BULK INSERT CSVTest 
FROM 'c:\csvfile.csv' 
WITH 
(
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
) 

的SQL Server 2005 BULK INSERT無法弄清楚,引號裏的回車符行終止
如何克服?


UPDATE
貌似保持場內換行符的唯一方式是使用不同的行分隔符。所以,我想通過在它們前面放置一個管道來標記所有行來分隔換行符。我怎樣才能改變我的CSV看起來像這樣?

1001,John Smith,15 Main Street|
1002,Jane Smith,"2010 Rockliffe Dr.
Pleasantville, IL
USA"|
1003,Bill Karr,2820 West Ave.|

回答

0

確定,這裏就是我寫出來解決問題的一個小型的Java程序。
歡迎評論,更正和優化。

import java.io.*; 

public class PreBulkInsert 
{ 
    public static void main(String[] args) 
    { 
     if (args.length < 3) 
     { 
      System.out.println ("Usage:"); 
      System.out.println (" java PreBulkInsert input_file output_file separator_character"); 
      System.exit(0); 
     } 

     try 
     { 
      boolean firstQuoteFound = false; 
      int fromIndex; 
      int lineCounter = 0; 
      String str; 

      BufferedReader in = new BufferedReader(new FileReader(args[0])); 
      BufferedWriter out = new BufferedWriter(new FileWriter(args[1])); 
      String newRowSeparator = args[2]; 

      while ((str = in.readLine()) != null) 
      { 
       fromIndex = -1; 
       do 
       { 
        fromIndex = str.indexOf('"', fromIndex + 1); 
        if (fromIndex > -1) 
         firstQuoteFound = !firstQuoteFound; 
       } while (fromIndex > -1); 

       if (!firstQuoteFound) 
        out.write(str + newRowSeparator + "\r\n"); 
       else 
        out.write(str + "\r\n"); 
       lineCounter++; 
      } 
      out.close(); 
      in.close(); 
      System.out.println("Done! Total of " + lineCounter + " lines were processed."); 
     } 
     catch (IOException e) 
     { 
      System.out.println(e.getMessage()); 
      System.exit(1); 
     }  
    } 
} 
0

根據所有知識(維基百科)源,csv採用新的生產線分開記錄。所以你有什麼是不正確的csv。

我的建議是,你寫一個perl程序來處理你的文件,並將每個記錄添加到分貝。

如果你不是一個Perl人,那麼你可以使用一個編程站點或看看是否有人會爲你編寫程序的解析部分。

補充:

可能的解決方案

由於OP指出,他可以改變輸入文件,我想改變這一切,不遵循「是保留字符序列,新線如XXX

這在很多編輯器的自動更換。在Windows,用UltraEdit包括正則表達式查找/替換功能

然後導入到數據庫管理系統,因爲你會ñ更長的嵌入式新行。

然後使用SQL Replace將XXX出現次數更改回新行。

+2

也來自所有知識源,「帶有嵌入換行符的字段必須包含在雙引號字符中」,所以輸入文件是有效的。 – Jimmy 2010-03-25 03:46:26

+0

沒有選項。它必須是由其他人在其他地方執行的SQL腳本。不過,我可以在編輯器中隨意修改CSV文件。 – 2010-03-25 03:49:40

1

SQL Server上的批量操作並不特別支持CSV,即使它們可以在文件仔細格式化時導入它們。我的建議是將所有字段值用引號括起來。 BULK INSERT可能會允許在一個字段值內回車。如果沒有,那麼您的下一個解決方案可能是一個Integration Services包。

有關更多信息,請參閱Preparing Data for Bulk Export or Import

0

除非CSV格式有效,否則無法導入。因此,您必須修復轉儲或手動使用搜索&替換修復不需要的新行字符。

+0

事情是我需要在筆記字段中保留這些新行字符。即使我可以刪除它們,CSV也是巨大的,我無法在編輯器中完全自動化。 – 2010-03-25 04:20:59

+0

嘗試轉儲而不添加註釋字段,然後再做只有註釋字段的另一個轉儲,但這次查看是否可以替換不需要的字符。你也可能需要導入兩次,因爲你有兩個轉儲。 – SoftwareGeek 2010-03-25 04:26:44

+0

如果你的意思是從數據庫轉儲 - 我不能這樣做:CSV按原樣發給我。 – 2010-03-25 12:08:49

0

如果您可以控制CSV文件的內容,則可以使用非換行符(可能只是CRLF)替換現場換行符(CRLF),然後在導入後運行腳本至再次用CRLF替換它們。

這就是MS Office產品(Excel,Access)處理此問題的方式。

+0

但是,如何可靠地區分場內換行符和行結束換行符? – 2010-03-25 11:58:09

+0

@ z-boss - 可能我誤解了你的問題 - 我推斷你可以控制CSV文件的製作。 – 2010-03-25 12:31:30

1

您可以用腳本將這些換行符按摩到一行中,例如,您可以使用GNU sed刪除換行符。例如

$ more file 
1001,John Smith,15 Main Street 
1002,Jane Smith,"2010 Rockliffe Dr. 
Pleasantville, IL 
USA" 
1003,Bill Karr,"2820 
West Ave" 

$ sed '/"/!s/$/|/;/.*\".*[^"]$/{ :a;N };/"$/ { s/$/|/ }' file 
1001,John Smith,15 Main Street| 
1002,Jane Smith,"2010 Rockliffe Dr. 
Pleasantville, IL 
USA"| 
1003,Bill Karr,"2820 
West Ave"| 

然後你可以批量插入。

編輯:

保存此:/"/!s/$/|/;/.*\".*[^"]$/{ :a;N };/"$/ { s/$/|/ }在一個文件,說myformat.sed。那麼這樣做在命令行上

​​

+0

我需要保留那些現場換行符。 sed是否可以在管道字符前加上所有不在場的換行符?通過這種方式,我會使用'| \ n'作爲批量插入的行分隔符,它會起作用。 – 2010-03-25 12:04:58

+0

我不明白。你的意思是這樣的:'2010 | Rockliffe博士| Pleasantville | IL USA'?如果沒有,你可能應該在你的問題中顯示你想要的輸出 – ghostdog74 2010-03-25 12:23:43

+0

我已經更新了我的問題。 – 2010-03-25 13:07:41