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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
18
0
20 815
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

Ответ принят как подходящий

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

будьте осторожны с заполнением журнала транзакций и т. д., если вы вставляете МНОГО строк.

Ian Ringrose 26.01.2010 12:54

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

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

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

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

BatchSize

: No of rows to be inserted per transaction . The Default is entire Data File. So a data file is in transaction

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

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

Согласно MSDN:

MAXERRORS :

Specifies the maximum number of syntax errors allowed in the data before the bulk-import operation is canceled. Each row that cannot be imported by the bulk-import operation is ignored and counted as one error. If max_errors is not specified, the default is 10.

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

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

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

В чем смысл BatchSize = 1 вместо отдельных операторов INSERT?

proteus 25.01.2018 03:02

Я думаю, что размер партии = 1 совершает транзакцию, которая аналогична отдельным операторам вставки, но для более поздних версий требуются номера циклов и строк для вставки без дублирования. Согласны с вашим утверждением, но это можно сделать с помощью атрибутов BULK INSERT

Sai Bhasker Raju 29.01.2018 09:12

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