web-dev-qa-db-ja.com

一括挿入で「予期しないファイルの終わり」エラーの原因となった行を特定しますか?

私は一括挿入を行っています:

DECLARE @row_terminator CHAR;
SET @row_terminator = CHAR(10); -- or char(10)

DECLARE @stmt NVARCHAR(2000);
SET @stmt = '
  BULK INSERT accn_errors
   FROM ''F:\FullUnzipped\accn_errors_201205080105.txt''
   WITH 
      (
        firstrow=2,
FIELDTERMINATOR = ''|''  ,
ROWS_PER_BATCH=10000
   ,ROWTERMINATOR='''+@row_terminator+'''
   )'
exec sp_executesql @stmt;

次のエラーが発生しています:

Msg 4832, Level 16, State 1, Line 2
Bulk load: An unexpected end of file was encountered in the data file.
Msg 7399, Level 16, State 1, Line 2
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 2
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".

このエラーが発生した行を知る方法はありますか?

私は問題なく10,000,000行をインポートでき、その後エラーが発生します

問題のある行を見つけるには、errorfile指定子を使用します。

BULK INSERT myData
FROM 'C:\...\...\myData.csv'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
ERRORFILE = 'C:\...\...\myRubbishData.log' 
);

myRubbishData.logには問題のある行があり、コンパニオンファイルmyRubbishData.log.txtからファイルへの行番号とオフセットが提供されます。

コンパニオンファイルの例:

Row 3 File Offset 152 ErrorFile Offset 0 - HRESULT 0x80004005
Row 5 File Offset 268 ErrorFile Offset 60 - HRESULT 0x80004005
Row 7 File Offset 384 ErrorFile Offset 120 - HRESULT 0x80004005
Row 10 File Offset 600 ErrorFile Offset 180 - HRESULT 0x80004005
Row 12 File Offset 827 ErrorFile Offset 301 - HRESULT 0x80004005
Row 13 File Offset 942 ErrorFile Offset 416 - HRESULT 0x80004005
47
user1588622

楽しい楽しい楽しい。私はこれらの問題をデバッグする良い方法を見つけていないので、ブルートフォースを使用します。つまり、FirstRowオプションとLastRowオプションは非常に便利です。

LastRow = 2から始めて、試行を続けます。結果をスローアウェイテーブルにロードし、すぐに切り捨てることができます。

また、1行目でも問題が発生する可能性があることに注意してください。

5
Gordon Linoff

Bulkを使用してインポートしたcsvファイルがあります

BULK INSERT [Dashboard].[dbo].[3G_Volume]
FROM 'C:\3G_Volume.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '","',
ROWTERMINATOR = '\n'
)
GO

通常、このスクリプトを使用しましたが、まれにしか問題ありません。

このエラーが発生しました。

"OLEリンクサーバー"(null) "のDBプロバイダー" BULK "はエラーを報告しました。プロバイダーはエラーに関する情報を提供しませんでした。"

通常、これは最後の行に空白の値(null)がある場合に発生します。

データを確認するには、MS Access dbでcsvファイルをリンクする必要があります。(csvが140万行以下の場合は、Excelで開くことができます)

私のデータは約300万行なので、アクセスデータベースを使用する必要があります。

次に、空白のある最後の行の数を確認し、csvの合計行からヌル行の数を引きます。

末尾に2つの空白行があり、行の総数が30000005の場合、スクリプトは次のようになります。

BULK
INSERT [Dashboard].[dbo].[3G_Volume]
 FROM 'C:\3G_Volume.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '","',
ROWTERMINATOR = '\n',
Lastrow = 30000003
)
GO

乾杯... Mhelboy

3
Mhelboy

CHAR(10)が行終端記号である場合、BULK INSERTでしようとしているように引用符で囲むことができないと思います。ただし、それを示す文書化されていない方法があります。

ROWTERMINATOR = '0x0A'
3
Steve Kass

ええ-BULK INSERTは、エラーメッセージにもう少し詳細な意志がありますが、ゴードンが正しく指摘したように、これを回避する唯一の方法はブルートフォースアプローチを使用することです。ただし、最初に、取得しているエラーに基づいて、行ターミネーターを理解していないか、ファイルの最後に行ターミネーターがありません。 FIRSTROWとLASTROWを使用すると、その判断に役立ちます。

そのため、次のことを行う必要があります。

  1. ファイルの最後に行終了記号があることを確認してください。そうでない場合は、入れてもう一度やり直してください。また、最後の行に必要なフィールドがすべて含まれていることを確認してください。 「EOF」と表示されている場合、それが問題です。
  2. 各行の最後にLFがありますか?CR(\ n、0x0D)を試して、それが機能するかどうかを確認してください。
  3. まだ動かない? LASTROW = 2を設定して再試行してください。次に、LASTROW = 3を試してください。ファイルに3行を超える行があり、この手順が失敗した場合、行終了記号は機能していません。
2
Peter

私は同じ問題に遭遇しました。 Linuxで.csvを作成するシェルスクリプトを作成しました。この.csvをWindowsに持ち込んで、データの一括読み込みを試みました。カンマが「好き」ではありませんでした。理由を聞かないでください。しかし、一括インポートで区切り文字として*に変更し、.csvでカンマの検索と置換を*で実行しました。 ..デリミタとして〜に変更しました。これは機能しました...タブも機能しました-カンマが好きではありませんでした。

1
user2125311

私の経験では、これはほとんどの場合、最後の2行の何かによって引き起こされます。 tailインポートファイルを使用すると、引き続きエラーが発生します。次に、CR、LF、EOFなどの非印刷文字を表示できるフルテキストエディターで開きます。理由がわからなくても、それを使って作業に取り組めるようになるはずです。例: 最後の行の行ターミネーターでBULK INSERTが失敗します

0
feetwet

すべてのフィールドを文字列に変換し、共通のFIELDTERMINATORを使用することで問題を回避しました。これはうまくいきました:

BULK INSERT [dbo].[workingBulkInsert]  
FROM 'C:\Data\myfile.txt' WITH (
   ROWTERMINATOR = '\n', 
   FIELDTERMINATOR = ',' 
)

データファイルは次のようになります。

"01502","1470"
"01504","686"
"02167","882"
"106354","882"
"106355","784"
"106872","784"

2番目のフィールドは、二重引用符区切り文字のない10進数型でした(1470.00など)。両方を文字列としてフォーマットすると、エラーがなくなりました。

0
Karl Hoaglund