Question

If I run the following query in SQL Server 2000 Query Analyzer:

BULK INSERT  OurTable 
FROM 'c:\OurTable.txt' 
WITH (CODEPAGE = 'RAW', DATAFILETYPE = 'char', FIELDTERMINATOR = '\t', ROWS_PER_BATCH = 10000, TABLOCK)

On a text file that conforms to OurTable's schema for 40 lines, but then changes format for the last 20 lines (lets say the last 20 lines have fewer fields), I receive an error. However, the first 40 lines are committed to the table. Is there something about the way I'm calling Bulk Insert that makes it not be transactional, or do I need to do something explicit to force it to rollback on failure?

Was it helpful?

Solution

BULK INSERT acts as a series of individual INSERT statements and thus, if the job fails, it doesn't roll back all of the committed inserts.

It can, however, be placed within a transaction so you could do something like this:

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

OTHER TIPS

You can rollback the inserts . To do that we need to understand two things first

BatchSize

: No of rows to be inserted per transaction . The Default is entire Data File. So a data file is in transaction

Say you have a text file which has 10 rows and row 8 and Row 7 has some invalid details . When you Bulk Insert the file without specifying or with specifying batch Size , 8 out of 10 get inserted into the table. The Invalid Row's i.e. 8th and 7th gets failed and doesn't get inserted.

This Happens because the Default MAXERRORS count is 10 per transaction.

As Per MSDN :

MAXERRORS :

Specifies the maximum number of syntax errors allowed in the data before the bulk-import operation is canceled. Each row that cannot be imported by the bulk-import operation is ignored and counted as one error. If max_errors is not specified, the default is 10.

So Inorder to fail all the 10 rows even if one is invalid we need to set MAXERRORS=1 and BatchSize=1 Here the number of BatchSize also matters.

If you specify BatchSize and the invalid row is inside the particular batch , it will rollback the particular batch only ,not the entire data set. So be careful while choosing this option

Hope this solves the issue.

As stated in the BATCHSIZE definition for BULK INSERT in MSDN Library (http://msdn.microsoft.com/en-us/library/ms188365(v=sql.105).aspx) :

"If this fails, SQL Server commits or rolls back the transaction for every batch..."

In conclusion is not necessary to add transactionality to Bulk Insert.

Try to put it inside user-defined transaction and see what happens. Actually it should roll-back as you described it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top