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

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


当前回答

如果你可以使用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()工作得很好,但你不应该忘记return语句,否则脚本将继续没有错误!(因此,raiserror不是一个“throwerror”;-)),当然,如果需要,还会进行回滚!

Raiserror()用于告诉执行脚本的人出错了。

如果你只是在Management Studio中执行一个脚本,并且想要在第一个错误时停止执行或回滚事务(如果使用),那么我认为最好的方法是使用try catch block (SQL 2005以后)。 如果您正在执行脚本文件,这在Management studio中工作得很好。 Stored proc也总是可以使用这个。

将适当的代码块包装在try catch块中。然后,如果您愿意,可以使用严重程度为11的Raiserror事件,以便中断到catch块。如果你只想抛出错误,但在try块内继续执行,那么使用较低的严重程度。

试一试……抓住(transact - sql)

raiserror方法

raiserror('Oh no a fatal error', 20, -1) with log

这将终止连接,从而停止脚本的其余部分的运行。

注意,要以这种方式工作,严重级别20或更高级别和WITH LOG选项都是必需的。

这甚至适用于GO语句,例如。

print 'hi'
go
raiserror('Oh no a fatal error', 20, -1) with log
go
print 'ho'

将给你输出:

hi
Msg 2745, Level 16, State 2, Line 1
Process ID 51 has raised user error 50000, severity 20. SQL Server is terminating this process.
Msg 50000, Level 20, State 1, Line 1
Oh no a fatal error
Msg 0, Level 20, State 0, Line 0
A severe error occurred on the current command.  The results, if any, should be discarded.

注意没有打印'ho'。

警告:

这只在您以admin ('sysadmin'角色)身份登录时有效,并且没有数据库连接。 如果您不是以管理员身份登录,则RAISEERROR()调用本身将失败,脚本将继续执行。 当使用sqlcmd.exe调用时,将报告退出代码2745。

参考:http://www.mydatabasesupport.com/forums/ms - sqlserver/174037 - sql - server - 2000 -中止整个script.html # post761334

noexec方法

另一个使用GO语句的方法是set noexec on (docs)。这将导致跳过脚本的其余部分。它不会终止连接,但在执行任何命令之前,您需要再次关闭noexec。

例子:

print 'hi'
go

print 'Fatal error, script will not continue!'
set noexec on

print 'ho'
go

-- last line of the script
set noexec off -- Turn execution back on; only needed in SSMS, so as to be able 
               -- to run this script again in the same session.

我用一个事务成功地扩展了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。因此,我可以很好地提交或回滚事务。