T-SQL:出现错误时控制流程

Car*_*est 1 t-sql

Sup人,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 
Run Code Online (Sandbox Code Playgroud)

呃,有人吗?

gbn*_*gbn 5

没有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
Run Code Online (Sandbox Code Playgroud)

强制性背景阅读是Erland Sommarskog的"SQL 2005及更高版本中的错误处理":我们稍后会测试你的...