是否有一种方法可以立即停止SQL服务器中SQL脚本的执行,如“break”或“exit”命令?
我有一个脚本,它在开始插入之前执行一些验证和查找,我希望它在任何验证或查找失败时停止。
是否有一种方法可以立即停止SQL服务器中SQL脚本的执行,如“break”或“exit”命令?
我有一个脚本,它在开始插入之前执行一些验证和查找,我希望它在任何验证或查找失败时停止。
当前回答
这些都不能用于“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 ....)
其他回答
在过去,我们使用了以下语句:效果最好:
RAISERROR ('Error! Connection dead', 20, 127) WITH LOG
你可以使用RAISERROR。
在SQL 2012+中,您可以使用THROW。
THROW 51000, 'Stopping execution because validation failed.', 0;
PRINT 'Still Executing'; -- This doesn't execute with THROW
从MSDN:
引发异常并将执行转移到TRY…CATCH构造的CATCH块…如果TRY…CATCH结构不可用,则会话结束。设置引发异常的行号和过程。级别设置为16。
只需使用RETURN(它可以在存储过程内部和外部工作)。
我用一个事务成功地扩展了noexec开/关解决方案,以全有或全无的方式运行脚本。
set noexec off
begin transaction
go
<First batch, do something here>
go
if @@error != 0 set noexec on;
<Second batch, do something here>
go
if @@error != 0 set noexec on;
<... etc>
declare @finished bit;
set @finished = 1;
SET noexec off;
IF @finished = 1
BEGIN
PRINT 'Committing changes'
COMMIT TRANSACTION
END
ELSE
BEGIN
PRINT 'Errors occured. Rolling back changes'
ROLLBACK TRANSACTION
END
显然,编译器“理解”IF中的@finished变量,即使有一个错误并且执行被禁用。但是,只有在未禁用执行时,该值才会设置为1。因此,我可以很好地提交或回滚事务。