Является ли SQL Server Bulk Insert Transactional?

Если я запустил следующий запрос в SQL Server 2000 Query Analyzer:

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

В текстовом файле, который соответствует схеме OurTable для 40 строк, но затем меняет формат для последних 20 строк (например, последние 20 строк имеют меньше полей), я получаю сообщение об ошибке. Однако первые 40 строк привязаны к таблице. Есть ли что-то в том, как я называю Bulk Insert, что делает его не транзакционным, или мне нужно сделать что-то явное, чтобы заставить его откатиться при ошибке?

Ответы

Ответ 1

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 для BULK INSERT в библиотеке MSDN (http://msdn.microsoft.com/en-us/library/ms188365(v=sql.105).aspx):

"Если это не удается, SQL Server совершает или откатывает транзакцию для каждой партии..."

В заключение нет необходимости добавлять транзакцию к Bulk Insert.

Ответ 3

Вы можете откатить вставки. Для этого нам нужно сначала понять две вещи:

BatchSize

: Количество строк для каждой транзакции. По умолчанию все Файл данных. Таким образом, файл данных находится в транзакции

Скажем, у вас есть текстовый файл с 10 строками и строкой 8, а в строке 7 есть некоторые недопустимые данные. Когда вы Bulk Вставьте файл без указания или с указанием размера партии, 8 из 10 встанут в таблицу. Недопустимая строка, т.е. 8-я и 7-я, не удалась и не вставлена.

Это происходит потому, что значение по умолчанию MAXERRORS составляет 10 за транзакцию.

Как в MSDN:

МАКСЕРРОРЫ:

Указывает максимальное количество синтаксических ошибок, допущенных в данных перед тем, как операция массового импорта будет отменена. Каждая строка, которая не может быть импортированный операцией массового импорта, игнорируется и считается как один ошибка. Если max_errors не указан, значение по умолчанию равно 10.

Так что Inorder, чтобы вывести из строя все 10 строк, даже если они недействительны, нам нужно установить MAXERRORS=1 и BatchSize=1 Здесь также имеет значение BatchSize.

Если вы укажете BatchSize и недопустимая строка находится внутри определенной партии, она откатит только конкретную пакетную версию, а не весь набор данных. Поэтому будьте осторожны при выборе этой опции

Надеюсь, что это решает проблему.

Ответ 4

Попробуйте поместить его в пользовательскую транзакцию и посмотрите, что произойдет. На самом деле он должен откатиться, как вы описали его.