首页 > 解决方案 > SQL Server 在不同类型的错误中停止执行的行为不同

问题描述

我有Alter Table陈述清单:

BEGIN

    ALTER TABLE TABLE1 ALTER COLUMN AA INT -- Error Here
    ALTER TABLE TABLE1 ALTER COLUMN BB INT
    PRINT('CONTINUE AFTER ERROR')

END

出错后它停止执行并跳过其他语句。

在输出中它只显示 1 个错误。

但在第二种情况下,我有一个 DROP INDEX 语句列表

BEGIN
    DROP INDEX TABLE1.INDEX1  -- Error Here
    DROP INDEX TABLE2.INDEX2
    PRINT('CONTINUE AFTER ERROR')
END

出现错误后,它会继续执行并打印错误日志和文本“CONTINUE AFTER ERROR”。

为什么会有这种差异?

标签: sqlsql-server

解决方案


行为上的差异是因为第一批ALTER TABLE语句是编译错误,而第二批DROP INDEX语句是运行时错误。

当批处理发生编译错误时,不执行任何代码,只返回编译错误。此外,由于没有代码执行时出现编译错误,因此甚至无法通过结构化错误处理来捕获错误:

BEGIN TRY
        ALTER TABLE TABLE1 ALTER COLUMN AA INT -- Error Here
        ALTER TABLE TABLE1 ALTER COLUMN BB INT
        PRINT('CONTINUE AFTER ERROR')
END TRY
BEGIN CATCH
    PRINT 'CAUGHT ERROR';
END CATCH;

消息 4902,级别 16,状态 1,第 4 行找不到对象“TABLE1”,因为它不存在或您没有权限。

当编译成功并发生运行时错误时,同一批次中的后续语句可能会或可能不会在错误后执行,具体取决于错误严重程度和XACT_ABORT setting.


推荐阅读