SQL Server の一括挿入はトランザクションですか?
-
09-06-2019 - |
質問
SQL Server 2000 クエリ アナライザで次のクエリを実行すると、次のようになります。
BULK INSERT OurTable
FROM 'c:\OurTable.txt'
WITH (CODEPAGE = 'RAW', DATAFILETYPE = 'char', FIELDTERMINATOR = '\t', ROWS_PER_BATCH = 10000, TABLOCK)
40 行は OurTable のスキーマに準拠しているが、最後の 20 行の形式が変更されているテキスト ファイル (最後の 20 行のフィールドが少ないとします) では、エラーが発生します。ただし、最初の 40 行はテーブルにコミットされます。Bulk Insert の呼び出し方法にトランザクション性がなくなる何かがあるのでしょうか、それとも失敗時に強制的にロールバックするために明示的に何かを行う必要があるのでしょうか?
解決
BULK INSERT
一連の個人として機能する INSERT
したがって、ジョブが失敗した場合、コミットされたすべての挿入がロールバックされるわけではありません。
ただし、トランザクション内に配置できるため、次のようなことができます。
BEGIN TRANSACTION
BEGIN TRY
BULK INSERT OurTable
FROM 'c:\OurTable.txt'
WITH (CODEPAGE = 'RAW', DATAFILETYPE = 'char', FIELDTERMINATOR = '\t',
ROWS_PER_BATCH = 10000, TABLOCK)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
他のヒント
挿入をロールバックできます。そのためには、まず 2 つのことを理解する必要があります
BatchSize
:トランザクションごとに挿入される行の数。デフォルトはデータファイル全体です。したがって、データファイルはトランザクション中です
10 行あるテキスト ファイルがあり、行 8 と行 7 に無効な詳細が含まれているとします。バッチ サイズ を指定せずに、またはバッチ サイズを指定してファイルを一括挿入すると、10 個のうち 8 個がテーブルに挿入されます。無効な行、つまり8番と7番は失敗して挿入されません。
この問題が発生するのは、デフォルトの MAXERRORS
カウントはトランザクションごとに 10 です。
MSDN によると:
最大エラー数 :
バルク輸入操作がキャンセルされる前に、データで許可されている構文エラーの最大数を指定します。バルク輸入操作によってインポートできない各行は無視され、1つのエラーとしてカウントされます。max_errors が指定されていない場合、デフォルトは 10 です。
したがって、1行が無効であっても10行すべてを失敗させるには、次のように設定する必要があります。 MAXERRORS=1
そして BatchSize=1
ここでは、BatchSize の数も重要です。
BatchSize を指定し、無効な行が特定のバッチ内にある場合、データ セット全体ではなく、特定のバッチのみがロールバックされます。したがって、このオプションを選択するときは注意してください
これで問題が解決することを願っています。
に記載されているように、 BATCHSIZE
MSDN ライブラリの BULK INSERT の定義 (http://msdn.microsoft.com/en-us/library/ms188365(v=sql.105).aspx) :
「これが失敗すると、SQL Server はバッチごとにトランザクションをコミットまたはロールバックします...」
結論として、一括挿入にトランザクション性を追加する必要はありません。
これをユーザー定義のトランザクション内に入れて、何が起こるかを確認してください。実際には、説明したようにロールバックするはずです。