Является ли SQL Server Bulk Insert Transactional? - PullRequest
16 голосов
/ 03 сентября 2008

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

Ответы [ 4 ]

21 голосов
/ 30 сентября 2008

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
3 голосов
/ 22 декабря 2016

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

BatchSize

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

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

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

Согласно MSDN:

МАКСЕРРОРЫ:

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

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

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

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

2 голосов
/ 01 марта 2012

Как указано в определении BATCHSIZE для BULK INSERT в библиотеке MSDN (http://msdn.microsoft.com/en-us/library/ms188365(v=sql.105).aspx):

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

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

0 голосов
/ 03 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...