Является ли 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
Попробуйте поместить его в пользовательскую транзакцию и посмотрите, что произойдет. На самом деле он должен откатиться, как вы описали его.