Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 raiserror и выходиз процедуры  [new]
minva
Member

Откуда: г. Калуга
Сообщений: 1213
написано, в BOL : Ошибки, созданные инструкцией RAISERROR, аналогичны ошибкам, созданным кодом компонента Database Engine

В начала ХП стоит SET XACT_ABORT ON. Почему при выполнении RAISERROR('qqqqq', 16, 1) не происходит выход из процедуры?
Ведь вроде как при включенной опции XACT_ABORT последующие операции не выполняются в случае ошибки?
Или в каком месте я недопонимаю? Пока приходится писать так:
RAISERROR('qqqqq', 16, 1) 
return -1 
11 ноя 11, 13:47    [11581529]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
aleks2
Guest
BOL:
When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.


Хде тут про завершение процедуры?
11 ноя 11, 14:00    [11581680]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
minva
Member

Откуда: г. Калуга
Сообщений: 1213
aleks2,

Блин, получается транзакция откатывается, а все последующие действия выполняются? непонятно....
11 ноя 11, 14:05    [11581727]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
minva
получается транзакция откатывается, а все последующие действия выполняются? непонятно..

А что в этом непонятного ?
11 ноя 11, 14:07    [11581743]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
Установка XACT_ABORT в ON, при возникновении рантайм-ошибки, будет приводить к завершению пакета и откату транзакции. Пользовательский raiserror рантайм-ошибкой не является.
11 ноя 11, 14:19    [11581881]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
minva
Member

Откуда: г. Калуга
Сообщений: 1213
Glory,

Я выполняю ОДНУ ХП. Стартует неявно трaнзакци, при завершении успешном она подтверждается.
Допустим внутри ХП что-то не сработало, транзакция должна откатиться. А после этого "что-то" стоит еще INSERT. Если он будет выполняться, то в рамках какой транзакции?
11 ноя 11, 14:19    [11581882]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
minva,

У вас после raiserror ничего не откатится если вы явно не напишете rollback.
Вот примерчик из БОЛ, чтобы почувствовать разницу.

IF OBJECT_ID(N't2', N'U') IS NOT NULL
    DROP TABLE t2;
GO
IF OBJECT_ID(N't1', N'U') IS NOT NULL
    DROP TABLE t1;
GO
CREATE TABLE t1
    (a INT NOT NULL PRIMARY KEY);
CREATE TABLE t2
    (a INT NOT NULL REFERENCES t1(a));
GO
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (3);
INSERT INTO t1 VALUES (4);
INSERT INTO t1 VALUES (6);
GO
SET XACT_ABORT OFF;
GO
BEGIN TRANSACTION;
INSERT INTO t2 VALUES (1);
INSERT INTO t2 VALUES (2); -- Foreign key error.
INSERT INTO t2 VALUES (3);
COMMIT TRANSACTION;
GO
SET XACT_ABORT ON;
GO
BEGIN TRANSACTION;
INSERT INTO t2 VALUES (4);

-- попробуйте поочередно закомментировать то одну то другую строку
INSERT INTO t2 VALUES (5); -- Foreign key error.
--RAISERROR('qqqqq', 16, 1); --Raiserror error

INSERT INTO t2 VALUES (6);
COMMIT TRANSACTION;
GO
-- SELECT shows only keys 1 and 3 added. 
-- Key 2 insert failed and was rolled back, but
-- XACT_ABORT was OFF and rest of transaction
-- succeeded.
-- Key 5 insert error with XACT_ABORT ON caused
-- all of the second transaction to roll back.
SELECT *
    FROM t2;
GO
А вообще, согласен, что путает и вызывает вопросы. Вроде как еррор, и если не знать, то логично как-то ожидать немного другого поведения, имхо, неплохо было бы указать это в документации явно.

An SQL text by Erland Sommarskog, SQL Server MVP
Beware, though, that even when XACT_ABORT is ON, not all errors terminate the batch. Here are the exceptions I know of:
Errors you raise yourself with RAISERROR.
Compilation errors (which normally terminate the scope) do not terminate the batch.
Error 266, Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing.

So at a minimum you still need to check @@error after the execution of a stored procedure or a block of dynamic SQL even if you use XACT_ABORT ON

Error Handling
11 ноя 11, 14:31    [11582015]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
minva,

вот кстати еще на тему, вы не одиноки. порылся быстренько в коннекте (обратная связь с разработчиками)
Have RAISERROR work with XACT_ABORT
Вот ответ из МС
SQL Server Engine Team
Hello
Thank you for your feedback. By design, the XACT_ABORT set option does not impact the behavior of the RAISERROR statement. We will consider your feedback to modify this behavior for a future release of SQL Server.


Так что можете голосовать за то, чтобы они поменяли поведение, там уже есть 13 голосов =)
11 ноя 11, 14:47    [11582164]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104751
minva
Я выполняю ОДНУ ХП. Стартует неявно трaнзакци, при завершении успешном она подтверждается.
Допустим внутри ХП что-то не сработало, транзакция должна откатиться. А после этого "что-то" стоит еще INSERT. Если он будет выполняться, то в рамках какой транзакции?

А какая связь между транзакцией и процедурой то ?
Это независимые вещи
11 ноя 11, 14:55    [11582251]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
minva
Member

Откуда: г. Калуга
Сообщений: 1213
Glory,

Тогда подскажите где почитать?

Пусть имеем

Exec My_Procedure
Go

В самой процедуре есть insert и пара update

Явно begin Transaction нигде не указано.
Где и как в этом случае транзакция начинается и заканчивается?

BOL
Автоматическая фиксация транзакций
Режим по умолчанию для компонента Database Engine. Каждая отдельная инструкция языка Transact-SQL фиксируется после завершения. Нет необходимости указывать какие-либо инструкции для управления транзакциями.


Exec My_Procedure - это отдельная инструкция?
14 ноя 11, 15:41    [11594010]     Ответить | Цитировать Сообщить модератору
 Re: raiserror и выходиз процедуры  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
minva
Glory,

Тогда подскажите где почитать?

Пусть имеем

Exec My_Procedure
Go

В самой процедуре есть insert и пара update

Явно begin Transaction нигде не указано.
Где и как в этом случае транзакция начинается и заканчивается?

BOL
Автоматическая фиксация транзакций
Режим по умолчанию для компонента Database Engine. Каждая отдельная инструкция языка Transact-SQL фиксируется после завершения. Нет необходимости указывать какие-либо инструкции для управления транзакциями.


Exec My_Procedure - это отдельная инструкция?
Нет. В данном случае под инструкциями понимаются INSERT и UPDATE внутри процедуры.
Если не написать явно начало транзакции и запретить неявную транзакцию,
каждая инструкция выполнится в своей транзакции, которую завершит до следующей инструкции.
14 ноя 11, 15:58    [11594159]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить