web-dev-qa-db-ja.com

一括挿入、SQL Server 2000、UNIX改行

UNIXの改行を含むデータベースに.csvファイルを挿入しようとしています。私が実行しているコマンドは次のとおりです。

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

ファイルをWindows形式に変換した場合、ロードは機能しますが、回避できる場合はこの追加の手順を実行したくありません。何か案は?

35
John Oxley

同じ問題が発生し、SAPから2つのUNIXファイルを少なくとも1日に数回読み取る必要があるため、貢献を強いられました。したがって、私はunix2dosを使用する代わりに、手動による介入が少なく、プログラミングによる自動化が必要です。

前述のように、Char(10)はSQL文字列内で機能します。 SQL文字列を使用したくなかったので、 '' '' + Char(10)+ '' ''を使用しましたが、何らかの理由でこれがコンパイルされませんでした。

非常に洗練された機能は次のとおりです:(ROWTERMINATOR = '0x0a')

Hexで問題が解決しました!

これが誰かを助けることを願っています。

100
Randy J

答えてくれたすべての人に感謝しますが、私は自分の好みの解決策を見つけました。

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セクションで式を評価できるようには見えません。

上記のことは、コマンドの文字列を作成し、それを実行することです。追加のファイルを作成するか、追加の手順を実行する必要性を適切に回避します。

14
John Oxley

構文が

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

eXECコマンドとともに使用すると機能します。

複数のROWTERMINATOR文字(たとえば、パイプとUNIXの改行)がある場合、この構文は次のとおりです。

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

それはそれよりも少し複雑です! SQL ServerにROWTERMINATOR = '\ n'と指示すると、これはWindowsでのデフォルトの行ターミネーターを意味すると解釈し、実際には「\ r\n」です(C/C++表記を使用)。行ターミネータが本当に「\ n」の場合は、上記の動的SQLを使用する必要があります。 1時間の大部分を費やして、なぜBULK INSERTと一緒に使用しても\ nが本当に意味しないのかを理解しました!

2
Will Rayer

1つのオプションは bcp を使用し、改行文字として'\n'を使用して制御ファイルを設定することです。

希望しないことを示しましたが、もう1つのオプションは nix2dos を使用して、ファイルを'\r\n'の改行で1つに前処理することです。

最後に、BULK INSERTFORMATFILEオプションを使用できます。これは、bcp制御ファイルを使用してインポート形式を指定します。

私には、2つの一般的な方法があると思われます。SQLスクリプトでCSVを読み取る別の方法、またはCSVを事前に多数の方法で変換できます(bcp、unix2dos、1つであれば-物事の王様、コードエディターを使用してファイルを修正することもできます)。

ただし、追加の手順が必要になります。

このSQLがプログラムから起動された場合、そのプログラムの行末を変換することができます。その場合、変換を自分でコーディングすることにした場合、次のことに注意する必要があります。1.行末が\ n 2.または\ r\n 3.または\ r(Mac!)4。申し訳ありませんが、\ r\nと他の行が含まれている可能性があります。CSVのソースを制御しない限り、どのような組み合わせも可能です。

わかった、わかった。可能性4ははるかに高い。それはメールで起こりますが、それは別の話です。

0
Philippe Payant

これが原因です。 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コードが解析されているときに、char(10)がLF文字で置き換えられていないためです(すでに単一引用符で囲まれているためです)。または、次のように解釈される可能性があります。

(ROWTERMINATOR =
     )

@bulk_cmdの内容をエコー出力するとどうなりますか?

0
BIBD

「ROWTERMINATOR = '\ n'」で十分だと思います。 「隠し文字」を表示するツールでファイルを開いて、思いどおりに行が終了していることを確認することをお勧めします。私はこのようなことのためにnotepad ++を使います。

0
BankZ