T-SQL: поток управления в случае ошибок - PullRequest
1 голос
/ 17 августа 2011

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

    BEGIN TRANSACTION;

SET @sSystemLogDataId  = CONVERT(NCHAR(36), NEWID());
INSERT INTO crddata.crd_systemlogdata (systemdataid,systemlogid,userid,
    actiondatetime,actionstate)
    VALUES(@sSystemLogDataId,@inSystemLogId,@sUserId,GETDATE(),@nActionState);
SET @nError = @@ERROR;

IF (1 = @nChangeMassprintTaskStatus) AND (0 = @nError)
BEGIN
    UPDATE crddata.crd_massprinttasks SET massprinttaskstatus=@nMassprintTaskStatus
        WHERE massprinttaskid = @inMassprintTaskId;
    SET @nError = @@ERROR;
END

IF (@MassprintTaskType <> 1) AND (27 = @nActionState) AND (0 = @nError)
BEGIN
    UPDATE crddata.crd_massprinttasks SET massprinttasktype=1
        WHERE massprinttaskid = @inMassprintTaskId;
    SET @nError = @@ERROR;
END

IF 0 = @nError
BEGIN
    COMMIT TRANSACTION;
END
ELSE
BEGIN
    ROLLBACK TRANSACTION;
END 

Помогите, кто-нибудь?

Ответы [ 2 ]

5 голосов
/ 17 августа 2011

Без TRY / CATCH, это не пуленепробиваемый.

Ошибки могут быть пакетным прерыванием (например, преобразования типов данных или ошибки, вызванные триггерами), что означает, что ROLLBACK не запускается.

У вас есть для использования TRY / CATCH, и я всегда использую SET XACT_ABORT ON *

SET XACT_ABORT, NOCOUNT ON;
BEGIN TRY

    BEGIN TRANSACTION;

    SET @sSystemLogDataId  = CONVERT(NCHAR(36), NEWID());
    INSERT INTO crddata.crd_systemlogdata (systemdataid,systemlogid,userid,
        actiondatetime,actionstate)
        VALUES(@sSystemLogDataId,@inSystemLogId,@sUserId,GETDATE(),@nActionState);

    IF (1 = @nChangeMassprintTaskStatus)
    BEGIN
        UPDATE crddata.crd_massprinttasks SET massprinttaskstatus=@nMassprintTaskStatus
            WHERE massprinttaskid = @inMassprintTaskId;
    END

    IF (@MassprintTaskType <> 1) AND (27 = @nActionState)
    BEGIN
        UPDATE crddata.crd_massprinttasks SET massprinttasktype=1
            WHERE massprinttaskid = @inMassprintTaskId;
    END

    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 --may already be rolled back by SET XACT_ABORT or a trigger
         ROLLBACK TRANSACTION;
    RAISERROR [rethrow caught error using ERROR_NUMBER(), ERROR_MESSAGE(), etc]
END CATCH

Обязательным фоновым чтением является «Обработка ошибок в SQL 2005 и более поздних версиях» Эрланда Соммарскога : мы проверим вас позже ...

0 голосов
/ 17 августа 2011

Создайте триггер, который вызовет исключение, если вставка / обновление некорректны

пример:

create table t (id int)

go

create trigger tr on t 
for insert 
as
if exists(select 1 from inserted where id = 0)
    raiserror('id is not valid', 16, 1)

go

insert t select 1

select @@error

insert t select 0

select @@error
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...