是否有一种方法可以立即停止SQL服务器中SQL脚本的执行,如“break”或“exit”命令?

我有一个脚本,它在开始插入之前执行一些验证和查找,我希望它在任何验证或查找失败时停止。


当前回答

你可以使用GOTO语句改变执行流程:

IF @ValidationResult = 0
BEGIN
    PRINT 'Validation fault.'
    GOTO EndScript
END

/* our code */

EndScript:

其他回答

我一直在使用以下脚本,你可以在我的回答中看到更多细节。

RAISERROR ( 'Wrong Server!!!',18,1) WITH NOWAIT RETURN
    
    print 'here'
    
    select [was this executed]='Yes'

如果你可以使用SQLCMD模式,那么咒语

:on error exit

(包括冒号)将导致RAISERROR实际停止脚本。例如,

:on error exit

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SOMETABLE]') AND type in (N'U')) 
    RaisError ('This is not a Valid Instance Database', 15, 10)
GO

print 'Keep Working'

将输出:

Msg 50000, Level 15, State 10, Line 3
This is not a Valid Instance Database
** An error was encountered during execution of batch. Exiting.

批次就会停止。如果SQLCMD模式未打开,则会得到关于冒号的解析错误。不幸的是,如果脚本没有在SQLCMD模式下运行,那么它并不是完全防弹的,SQL management Studio甚至可以轻松地跳过解析时间错误!不过,如果您从命令行运行它们,这是没问题的。

你可以使用RAISERROR。

这些都不能用于“GO”语句。在这段代码中,无论严重程度是10还是11,都将得到最终的PRINT语句。

测试脚本:

-- =================================
PRINT 'Start Test 1 - RAISERROR'

IF 1 = 1 BEGIN
    RAISERROR('Error 1, level 11', 11, 1)
    RETURN
END

IF 1 = 1 BEGIN
    RAISERROR('Error 2, level 11', 11, 1)
    RETURN
END
GO

PRINT 'Test 1 - After GO'
GO

-- =================================
PRINT 'Start Test 2 - Try/Catch'

BEGIN TRY
    SELECT (1 / 0) AS CauseError
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE() AS ErrorMessage
    RAISERROR('Error in TRY, level 11', 11, 1)
    RETURN
END CATCH
GO

PRINT 'Test 2 - After GO'
GO

结果:

Start Test 1 - RAISERROR
Msg 50000, Level 11, State 1, Line 5
Error 1, level 11
Test 1 - After GO
Start Test 2 - Try/Catch
 CauseError
-----------

ErrorMessage
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Divide by zero error encountered.

Msg 50000, Level 11, State 1, Line 10
Error in TRY, level 11
Test 2 - After GO

实现这一功能的唯一方法是编写没有GO语句的脚本。有时候这很简单。有时候真的很困难。(使用IF @error <> 0 BEGIN ....)

将它包含在try catch块中,然后执行将被转移到catch。

BEGIN TRY
    PRINT 'This will be printed'
    RAISERROR ('Custom Exception', 16, 1);
    PRINT 'This will not be printed'
END TRY
BEGIN CATCH
    PRINT 'This will be printed 2nd'
END CATCH;