Является ли массовая вставка SQL Server транзакционной?

StackOverflow https://stackoverflow.com/questions/41869

Вопрос

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

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

Это было полезно?

Решение

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

Другие советы

Вы можете откатить вставки .Чтобы сделать это, нам сначала нужно понять две вещи

BatchSize

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

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

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

Согласно MSDN :

МАКСИМАЛЬНЫЕ ОШИБКИ :

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

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

Если вы укажете BatchSize и недопустимая строка находится внутри конкретного пакета, будет выполнен откат только конкретного пакета, а не всего набора данных.Так что будьте осторожны при выборе этого варианта

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

Как указано в BATCHSIZE определение для МАССОВОЙ ВСТАВКИ в библиотеку MSDN (http://msdn.microsoft.com/en-us/library/ms188365 (v=sql.105).aspx) :

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top