2008-09-03 14 views
14

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

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

ответ

18

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

Будьте осторожны при заполнении журнала транзакций и т. Д., Если вы вставляете много строк. – 2010-01-26 09:54:34

0

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

2

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

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

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

+0

[Microsoft documentation suckzz !!] (http://technet.microsoft.com/es-es/library/ms188365.aspx) Два дня тестирования, и, наконец, я заметил, что BULK INSERT не поддерживает откат при ошибке транзакции уровня компиляции. Я имею в виду, вам нужно создать запрос сохраненной процедуры для массового ввода, а затем окружить exec your_procedure «try/catch». Также очень важно определить MAXERRORS = 0, чтобы немедленно поймать первую ошибку. – 2012-03-08 06:54:42

2

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

BatchSize

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

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

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

В соответствии с MSDN:

MaxErrors:

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

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

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

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

+0

Какой смысл BatchSize = 1 вместо наличия отдельных инструкций INSERT? – proteus 2018-01-25 00:02:31