SQL Server:如何在查询分析器中中止一系列批处理?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server:如何在查询分析器中中止一系列批处理?相关的知识,希望对你有一定的参考价值。
我有一系列由特殊的查询分析器批处理分隔符关键字分隔的T-SQL语句:
GO
如果一个批次失败,我需要查询分析器不尝试后续批次 - 我希望它停止处理一系列批次。
例如:
PRINT 'This runs'
go
SELECT 0/0, 'This causes an error'
go
PRINT 'This should not run'
go
输出:
This runs
Server: Msg 8134, Level 16, State 1, Line 2
Divide by zero error encountered.
This should not run
可能?
更新
实际使用中的一个例子可能是:
sp_rename 'Shelby', 'Kirsten'
go
DROP VIEW PeekAView
go
CREATE VIEW PeekAViewAS
SELECT * FROM Kirsten
go
我是这样做的:
PRINT 'This runs'
go
SELECT 0/0, 'This causes an error'
go
if (@@error <> 0)
Begin
set nocount on
set noexec on
End
GO
PRINT 'This should not run'
go
set noexec off
set nocount off
GO
“noexec”模式使SSMS处于一种只编译T-SQL并且实际上不执行它的状态。它类似于意外按下Parse工具栏按钮(Ctrl + F5)而不是Execute(F5)。
不要忘记在脚本结束时关闭noexec。否则,用户会因永久“命令已成功完成”而感到困惑。消息。
我在后续批处理中使用对@@ error的检查,而不是使用TRY CATCH块。在下一批中使用@@ error将捕获编译错误,例如“表不存在”。
除了noexec模式,我还切换了nocount模式。启用noexec模式并关闭nocount后,您的查询仍将报告消息“(0行(s)受影响)”。该消息始终报告零行,因为您处于noexec模式。然而,转向nocount会抑制这些消息。
另请注意,如果正在运行SQL Server 2005,则跳过的命令如果引用了不存在的表,则可能仍会显示错误消息,如果批处理中的第一个命令,则该命令仍然是命令。使用伪造的Print语句强制命令成为批处理中的第二个命令可以抑制此操作。有关详细信息,请参阅MS Bug #569263。
您可以激活“查询,SQLCMD模式”菜单选项,并将以下内容放在脚本的开头:
:on error exit
这将在发生错误时停止执行,即使存在后续批处理也是如此。
只需确保在没有启用SQLCMD模式的情况下不小心运行脚本,因为您将获得忽略错误的典型行为。
当我需要这样做时,我发出一个严重级为20的RAISERROR。这个或更高级别将终止当前连接,并阻止后续的“GO批处理”执行。是的,它可能很尴尬,但它可以完成这项工作。
创建一个临时表;并在每个步骤后更新它(如果成功);然后通过验证表来检查上一步的成功。
create table #ScriptChecker (SuccessfullStep int)
-- Do Step One
Insert into #ScriptChecker
Select 1
-- Step 2
If exists (select * from #ScriptChecker where SuccessfullStep = 1)
-- Do Step 2 ...
基于@ u07ch的想法,但只在失败时插入...
create table #test (failure int)
if not exists (select * from #test)
BEGIN
print 'one' --sql here
END
go
if not exists (select * from #test)
BEGIN
print 'two'--sql here
END
go
if not exists (select * from #test)
BEGIN
print 'three' ---SQL SERVER 2000 version
--error--
SELECT 0/0, 'This causes an error'
IF @@ERROR!=0
BEGIN
insert into #test values (1)
PRINT 'ERROR'
END
end
go
if not exists (select * from #test)
BEGIN
print 'three' ---SQL SERVER 2005/2008 version
BEGIN TRY
--error--
SELECT 0/0, 'This causes an error'
END TRY
BEGIN CATCH
insert into #test values (1)
PRINT 'ERROR'
END CATCH
END
go
if not exists (select * from #test)
BEGIN
--sql here
print 'four'
END
go
输出2000:
one
two
three
----------- --------------------
Msg 8134, Level 16, State 1, Line 7
Divide by zero error encountered.
(1 row(s) affected)
ERROR
输出2005/2008:
one
two
three
----------- --------------------
(0 row(s) affected)
(1 row(s) affected)
ERROR
microsoft.public.sqlserver.programming组中的Erland Sommarskog有一个非常好的主意:
在您发布的更改脚本中,您需要采取防御措施,并使用IF @@ trancount> 0启动每个批处理。
运用
IF @@trancount > 0
更清洁。
以上是关于SQL Server:如何在查询分析器中中止一系列批处理?的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server调优系列基础篇(常用运算符总结——三种物理连接方式剖析)