2009-01-26 103 views
30

我試圖用unix換行符將一個.csv文件插入到數據庫中。我運行的命令是:批量插入,SQL Server 2000,unix linebreaks

BULK INSERT table_name 
FROM 'C:\file.csv' 
WITH 
( 
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
) 

如果我將文件轉換成Windows格式負荷工作,但我不想做這個額外的步驟,如果能夠避免它。有任何想法嗎?

回答

92

由於我遇到同樣的問題,我覺得不得不貢獻自己的力量,我需要每天至少閱讀兩次來自SAP的UNIX文件。因此,我不需要使用unix2dos,而是通過編程來減少手動干預和更多自動化操作。

如上所述,Char(10)在sql字符串中工作。我不想使用一個sql字符串,所以我使用''''+ Char(10)+'''',但由於某種原因,這沒有編譯。

做什麼工作很光滑是:用(ROWTERMINATOR = '0X0A')

問題六角解決了!

希望這可以幫助別人。

1

一種選擇是使用bcp,併成立了一個控制文件,'\n'作爲換行符。

雖然您已經表明不想使用,但另一種選擇是使用unix2dos將文件預處理爲帶有'\r\n'換行符的文件。

最後,您可以使用FORMATFILE選項上BULK INSERT。這將使用bcp控制文件來指定導入格式。

+0

我想批量插入稱爲BCP模塊。我錯了嗎? – 2009-01-26 14:39:45

+0

它的確如此,因此它能夠使用bcp文件來指定輸入格式。 – ConcernedOfTunbridgeWells 2009-01-26 17:49:19

0

在我看來,可以採取兩種一般途徑:在SQL腳本中讀取CSV的一些替代方法,或者使用許多方法事先轉換CSV(bcp,unix2dos,如果它是一個事物的一次性王,你甚至可以使用你的代碼編輯器爲你修復這個文件)。

但是你將不得不有一個額外的步驟!

如果此SQL是從程序啓動的,則可能需要在該程序中轉換行結束符。在這種情況下,你決定編寫自己的轉換,這裏是你需要注意的: 1.行結束可能是N \ 2或\ r \ n 3.甚至\ R(蘋果機! ) 4.很好的悲傷,可能是某些行\ r \ n和其他\ n,任何組合都是可能的,除非您控制CSV來自哪裏

好,好的。可能性4牽強附會。它發生在電子郵件中,但那是另一回事。

13

感謝所有誰回答,但我找到了我的首選解決方案。

當您告訴SQL Server ROWTERMINATOR ='\ n'時,它將此解釋爲Windows下實際爲「\ r \ n」(使用C/C++表示法)的默認行終止符。如果你的行結束符真的只是「\ n」,你將不得不使用下面顯示的動態SQL。

DECLARE @bulk_cmd varchar(1000) 
SET @bulk_cmd = 'BULK INSERT table_name 
FROM ''C:\file.csv'' 
WITH (FIELDTERMINATOR = '','', ROWTERMINATOR = '''+CHAR(10)+''')' 
EXEC (@bulk_cmd) 

爲什麼你不能說BULK INSERT ...(ROWTERMINATOR = CHAR(10))超越了我。它看起來不像可以在命令的WITH部分中評估任何表達式。

上面做的是創建一個命令的字符串並執行它。整潔地避開創建額外文件的需求或者執行額外的步驟。

0

我會認爲「ROWTERMINATOR ='\ n'」會起作用。我建議在顯示「隱藏字符」的工具中打開該文件,以確保線路正在像您想象的那樣終止。我使用記事本++這樣的事情。

+0

是的,你會認爲它會起作用。我們大多數人也是如此。但事實並非如此。 `\ n`自動替換爲`\ r \ n`,因此需要其他解決方法來自行獲取LF。 – 2016-09-14 15:36:29

0

歸結到這一點。 Unix使用LF(ctrl-J),MS-DOS/Windows使用CR/LF(ctrl-M/Ctrl-J)。

當您在Unix上使用'\ n'時,它將被轉換爲LF字符。在MS-DOS/Windows上它被轉換爲CR/LF。當您的導入運行在Unix格式的文件上時,它只能看到一個LF。因此,首先通過unix2dos運行文件通常更容易。但正如你在原文中所說的那樣,你不想這樣做(我會假設你不能這麼做)。

你爲什麼不能做:

(ROWTERMINATOR = CHAR(10)) 

大概是因爲被解析的SQL代碼時,它不與LF字符替換的字符(10),(因爲它是在單引號已經包裹)。或者可能將其解釋爲:

(ROWTERMINATOR = 
    ) 

當您回顯@bulk_cmd的內容時會發生什麼?

2

這比這更復雜一點!當你告訴SQL Server ROWTERMINATOR ='\ n'時,它將它解釋爲Windows下的默認行終止符,它實際上是「\ r \ n」(使用C/C++符號)。如果你的行結束符真的只是「\ n」,你將不得不使用上面顯示的動態SQL。我剛剛花了一個小時的最佳時間,弄清楚爲什麼\ n不真正代表\ n與BULK INSERT一起使用!

3

我確認有EXEC命令一起使用時的語法

ROWTERMINATOR = '''+CHAR(10)+''' 

作品。

如果你有多個ROWTERMINATOR字符(如管道和UNIX換行),那麼這個語法是:

ROWTERMINATOR = '''+CHAR(124)+''+CHAR(10)+'''