Tsql T-SQL:发生错误时的控制流

Tsql T-SQL:发生错误时的控制流,tsql,Tsql,各位,INSERT或UPDATE是否可能抛出一个异常来停止该过程?我有点为难,因为我把事务挂在一个似乎是防弹的代码中 BEGIN TRANSACTION; SET @sSystemLogDataId = CONVERT(NCHAR(36), NEWID()); INSERT INTO crddata.crd_systemlogdata (systemdataid,systemlogid,userid, actiondatetime,actionstate) VALUE

各位,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 

哈尔普,有人吗?

没有尝试/捕捉,这不是防弹的

错误可以是批处理中止,例如数据类型转换或触发器引发的错误,这意味着回滚不会运行

您必须使用TRY/CATCH,我也总是使用SET-XACT\u-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

必须阅读的背景资料是Erland Sommarskog的:我们稍后会对您进行测试…

没有TRY/CATCH,这不是防弹的

错误可以是批处理中止,例如数据类型转换或触发器引发的错误,这意味着回滚不会运行

您必须使用TRY/CATCH,我也总是使用SET-XACT\u-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

Erland Sommarskog的强制后台读取:我们稍后将对您进行测试…

创建一个触发器,如果插入/更新不正确,该触发器将引发异常

例如:

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

创建一个触发器,该触发器将在插入/更新不正确时引发异常

例如:

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

触发器将中止SQL批处理,并且不会发生回滚。。。这就是问题想要解决的问题…触发器将中止SQL批处理,并且不会发生回滚。。。这就是问题想要解决的。。。