Member 14800672 Ответов: 1

Как откатить назад, если вставлено 0 записей


Так что я хочу
а. вставить в таблицу 1
б. вставить в табл. 2
c. обновление таблицы 3

если в таблицу 2 вставлено 0 записей, я не хочу, чтобы вставка в таблицу 1 происходила


кроме того, эти три шага должны быть успешно завершены вместе

Что я уже пробовал:

create PROCEDURE [dbo].[sp]
	@Id1 int
	,@BBId int
        ,@Text nvarchar(100) =''
AS
Begin
  Begin TRY
	Begin transaction
	        declare @Id int
            
		INSERT INTO table1 
		select @Text where @Text <> ''

		SET @Id = SCOPE_IDENTITY()

		INSERT INTO table2 (Id1, @Id)
			select @Id1,@Id from table3
			where table3.BBId = @BBId AND table3.Flag= 0 and 
                        table3.Id1 = @Id1
		
		        UPDATE    table3
			SET       Flag= 1
			WHERE   
				 table3.BBId = @BBID 
				AND table3.Id1 = @Id1
	COMMIT TRANSACTION
  END TRY
  BEGIN CATCH
  ROLLBACK; 
  throw
  END CATCH  
END
Return 0

Sandeep Mewara

если 0 записей вставляются в таблицу 2 => оставляя случай ошибки в стороне, не будет ли это просто тогда, когда предложение where не приносит никаких данных?

INSERT INTO table2 (Id1, @Id)
			select @Id1,@Id from table3
			where table3.BBId = @BBId AND table3.Flag= 0 and 
                        table3.Id1 = @Id1

Выше SQL where предложение не имеет зависимости от table1, зачем ждать вставки таблицы 1? Так ведь?

Member 14800672

Это зависит от таблицы 1... Я беру @Id из таблицы 1 и использую его в таблице 2... Поэтому если в таблицу 2 вставлено 0 записей я не хочу чтобы вставка происходила в таблице 1

Sandeep Mewara

При каких обстоятельствах вы видите, что вставка в таблицу 2 потерпит неудачу?
Только если чмокающие враги ошибаются, и если это так, то ваша попытка-уловка сработает.

Таким образом, единственный допустимый способ, как ничего не вставляется, - это отсутствие записи, выбранной для вставки в таблицу 2, которая не зависит от первого шага. Я могу предоставить пример sql запрашиваемого потока и последовательности, но я не понимаю, почему вам нужно следовать этой последовательности, чтобы решить, фиксировать/откатывать

Member 14800672

вставка в таблицу 2 не приведет к ошибке, но будет вставлено 0 записей. Может быть, @Id1 ошибается... Поэтому, если @Id1 ошибочен, он будет вставлен в таблицу 1, он не будет вставлен в таблицу 2 или обновлять таблицу 3. Так что никаких ошибок здесь мой улов ничего не возьмет. Но я хочу, чтобы если я ничего не вставляю в таблицу 2, то я вообще не хочу, чтобы вставка в таблицу 1 происходила

Sandeep Mewara

Какое ограничение у вас есть в таблице 2, которое приведет к тому, что запись не будет вставлена из-за @Id1.

Когда вы говорите, что ничего не вставлено, разве запрос не выдаст ошибку, если по какой-либо причине он не вставляется? Мне все еще не ясно, когда не будет никакой ошибки, но 0 записей, вставленных в таблицу 2. (Кроме того, когда предложение where приносит 0 записей, которые не зависят от таблицы 1)

ZurdoDev

Просто проверьте @@ROWCOUNT и, если он равен 0, откатитесь назад.

Member 14800672

Я сделал это

создайте процедуру [dbo].[sp]
@Id1 int
,@BBId int
,@Text nvarchar(100) ="
АС
Начать
Начать транзакцию
объявить @Id int

Вставить в таблицу 1
выберите @Text, где @Text <> "

Набор @идентификатор = функция scope_identity()

Вставить в таблицу 2 (Id1, @Id)
выберите @Id1,@Id из таблицы 3
где табл. 3.BBId = @BBId и table3.Flag= 0 и
Таблица 3.Id1 = @Id1

IF(@@ROWCOUNT <= 0)
НАЧАТЬ

инструкция ROLLBACK Transaction;
вернуть
КОНЕЦ
еще
начать
Обновление таблицы 3
Установить флаг= 1
ГДЕ
Таблица 3.BBId = @BBID
И table3.Id1 = @Id1
конец
СОВЕРШЕНИЮ СДЕЛКИ
КОНЕЦ
Возвращает 0

когда я запускаю его в SQL, я не получаю никаких ошибок, однако когда я вызываю хранимую процедуру из .Net я получаю эту ошибку:
"Количество транзакций после выполнения указывает на несоответствие количества операторов BEGIN и COMMIT. Предыдущий счетчик = 1, текущий счетчик = 0.\r\nTransaction count after EXECUTE указывает на несоответствующее число операторов BEGIN и COMMIT. Предыдущее количество = 1, текущее значение счетчика = 0."

1 Ответов

Рейтинг:
1

W∴ Balboos, GHB

Я что-то упускаю, или это так же просто, как:

1) Держите откат обработки ошибок
2) После успешного выполнения ваших вставок и обновлений, убедитесь, что они действительно находятся в таблице Если какая-либо из них не отражает добавленные и обновленные записи, выполните откат.

Возможно, не самый эффективный маршрут, но он достаточно прост.


Member 14800672

Я сделал это

создайте процедуру [dbo].[sp]
@Id1 int
,@BBId int
,@Text nvarchar(100) ="
АС
Начать
Начать транзакцию
объявить @Id int

Вставить в таблицу 1
выберите @Text, где @Text <> "

Набор @идентификатор = функция scope_identity()

Вставить в таблицу 2 (Id1, @Id)
выберите @Id1,@Id из таблицы 3
где табл. 3.BBId = @BBId и table3.Flag= 0 и
Таблица 3.Id1 = @Id1

IF(@@ROWCOUNT <= 0)
НАЧАТЬ

инструкция ROLLBACK Transaction;
вернуть
КОНЕЦ
еще
начать
Обновление таблицы 3
Установить флаг= 1
ГДЕ
Таблица 3.BBId = @BBID
И table3.Id1 = @Id1
конец
СОВЕРШЕНИЮ СДЕЛКИ
КОНЕЦ
Возвращает 0

когда я запускаю его в SQL, я не получаю никаких ошибок, однако когда я вызываю хранимую процедуру из .Net я получаю эту ошибку:
"Количество транзакций после выполнения указывает на несоответствие количества операторов BEGIN и COMMIT. Предыдущий счетчик = 1, текущий счетчик = 0.\r\nTransaction count after EXECUTE указывает на несоответствующее число операторов BEGIN и COMMIT. Предыдущее количество = 1, текущее значение счетчика = 0."