2013-04-01 4 views

ответ

10

Вы можете поместить свои два заявления в TRY....CATCH блока и только совершить, если оба утверждения успеха:

BEGIN TRANSACTION 
BEGIN TRY 
    DELETE FROM dbo.MYTABLE WHERE [email protected]; 

    INSERT INTO dbo.MYTABLE (ID, NAME) 
     SELECT @ID, NAME 

    -- COMMIT only if both DELETE and INSERT worked .... 
    COMMIT TRANSACTION 
END TRY 
BEGIN CATCH 
    SELECT 
     ERROR_NUMBER() AS ErrorNumber, 
     ERROR_SEVERITY() AS ErrorSeverity, 
     ERROR_STATE() AS ErrorState, 
     ERROR_PROCEDURE() AS ErrorProcedure, 
     ERROR_LINE() AS ErrorLine, 
     ERROR_MESSAGE() AS ErrorMessage 

    -- ROLLBACK if either DELETE and INSERT failed .... 
    ROLLBACK TRANSACTION 
END CATCH 
+0

Только откатывает один ряд. Остальные из них исчезли :(можем ли мы сделать это на протяжении всего жизненного цикла хранимой процедуры? – NoviceDeveloper

+0

Это весь жизненный цикл вашего sp. Если вы говорите о запуске sp несколько раз и катите их все назад, если один ошибки, то вы должны изменить свой процесс для обработки наборов данных, а не строк. – HLGEM

+0

Хмм, я использовал табличный параметр и теперь он разворачивается. Так что это только для одной строки. – NoviceDeveloper

0

Вот еще один способ сделать то, что вы, кажется, пытается:

update myTable 
set name = @name 
where id = @id 
+0

, хотя это хороший метод, но это обновление, я ищу конкретный способ удаления и вставки запустите мою хранимую процедуру. – NoviceDeveloper

0
BEGIN TRAN 

Delete from MYTABLE where [email protected]; 

INSERT INTO MYTABLE (ID, NAME) 
SELECT @ID, NAME 

if @@error = 0 and @@trancount > 0 
    commit 
else 
    rollback 
+0

Это неверно и использует синтаксис, который shoudl больше не используется теперь, когда у нас есть блоки TRYCATCH, это не будет отменено, если дельта не сработает. Если вы используете ошибку @@, вы должны проверить его после каждого заявления. – HLGEM

+0

Это неверный результат. как говорится. Заявление о проблеме состояло в откате удаления, если вставка не удалась, поэтому требуется только проверка после вставки. Try..catch также можно использовать, но это необязательно. –

2

Включите xact_abort, чтобы отменить транзакцию при любой ошибке.

SET XACT_ABORT ON; 
BEGIN TRAN 
Delete from MYTABLE where [email protected]; 

INSERT INTO MYTABLE (ID, NAME) 
SELECT @ID, NAME 

COMMIT TRAN 
Смежные вопросы