SQL Server批处理错误处理问题

Jam*_*mes 1 sql t-sql sql-server error-handling transactions

如何让这批SQL最终到达RollBack Transaction部分?SQL只是停止在坏代码行上停止脚本执行.我知道我可以使用try/catch构造但是我更感兴趣的是在SQL添加try/catch之前这是如何处理的.

BEGIN TRAN

CREATE TABLE TempTable (c1 INT NULL)

INSERT INTO TempTable (c1) SELECT 1

INSERT INTO TempTable (c1) SELECT 'ABS'

IF (@@ERROR = 0) 
BEGIN
    PRINT 'no error'
    COMMIT TRAN
END
    ELSE
BEGIN
    PRINT 'error' -- Why does it never get here???????
    ROLLBACK TRAN
END
Run Code Online (Sandbox Code Playgroud)

gbn*_*gbn 8

在这种情况下,您的'ABS'是批量中止,因为它是一个CAST错误.在这里解释,在Erland Sommarskog的精彩文章中

你必须阅读这篇文章.比你需要了解的SQL错误处理更多.

此外,您必须测试每个语句.如果第一个INSERT失败,你仍然继续执行(除非你有XACT_ABORT ON.

BEGIN TRAN

CREATE TABLE TempTable (c1 INT NULL)

INSERT INTO TempTable (c1) SELECT 1
IF @@ERROR <> 0
    GOTO errhandler

INSERT INTO TempTable (c1) SELECT 'ABS'
IF @@ERROR <> 0
    GOTO errhandler

PRINT 'no error'
COMMIT TRAN
GOTO exitpoint

errhandler:
PRINT 'error' -- Why does it never get here???????
ROLLBACK TRAN

exitpoint:
Run Code Online (Sandbox Code Playgroud)

如果您有SQL Server 2000,那么除了添加更多检查,ISNUMERIC等之外,您没有很多选项.

如果您有SQL Server 2005,那么您应该真正使用新技术.几乎所有代码和执行错误都被清楚地捕获.

BEGIN TRY
    BEGIN TRAN

    CREATE TABLE TempTable (c1 INT NULL)

    INSERT INTO TempTable (c1) SELECT 1

    INSERT INTO TempTable (c1) SELECT 'ABS'

    PRINT 'no error'
    COMMIT TRAN
END TRY
BEGIN CATCH
    PRINT 'error' --It will get here for SQL 2005
    ROLLBACK TRAN
END CATCH
Run Code Online (Sandbox Code Playgroud)