SQL Server中的T-SQL STOP或ABORT命令
在Microsoft SQL Server T-SQL中是否有命令来告诉脚本停止处理? 我有一个脚本,我想保留用于存档的目的,但我不希望任何人运行它。
另一种解决scheme是通过使用GOTO
语句来改变脚本的执行stream程。
DECLARE @RunScript bit; SET @RunScript = 0; IF @RunScript != 1 BEGIN RAISERROR ('Raise Error does not stop processing, so we will call GOTO to skip over the script', 1, 1); GOTO Skipper -- This will skip over the script and go to Skipper END PRINT 'This is where your working script can go'; PRINT 'This is where your working script can go'; PRINT 'This is where your working script can go'; PRINT 'This is where your working script can go'; Skipper: -- Don't do nuttin!
警告! 以上样品来自我从Merrill Aldrich获得的例子。 在您盲目地实现GOTO
语句之前,我build议您阅读他的T-SQL脚本中的stream控制教程。
不,没有一个 – 你有几个select:
-
将整个脚本包装在一个很大的if / end块中,这个块很简单,确保不是真的(即“if 1 = 2 begin”) – 只有在脚本不包含任何GO语句的情况下,批量)
-
在顶部使用return语句(同样,由批分隔符限制)
-
使用基于连接的方法,这将确保整个脚本不执行(整个连接更加准确) – 使用脚本顶部的“SET PARSEONLY ON”或“SET NOEXEC ON” 。 这将确保连接中的所有语句(或直到所述set语句被closures)将不执行,而是仅被parsing/编译。
-
使用注释块来注释整个脚本(即/ *和* /)
编辑:演示“返回”语句是批处理特定的 – 请注意,您将继续在返回后看到结果集:
select 1 return go select 2 return select 3 go select 4 return select 5 select 6 go
为什么不简单地将以下内容添加到脚本的开头
PRINT 'INACTIVE SCRIPT' RETURN
要解决RETURN / GO问题,您可以将RAISERROR ('Oi! Stop!', 20, 1) WITH LOG
放在顶部。
这将按照MSDN上的RAISERRORclosures客户端连接。
非常大的缺点是你必须是系统pipe理员使用严重性20。
编辑:
一个简单的示范来对付泽西·杜德的评论…
RAISERROR ('Oi! Stop!', 20, 1) WITH LOG SELECT 'Will not run' GO SELECT 'Will not run' GO SELECT 'Will not run' GO
严重程度为20的RAISERROR将在事件查看器中报告为错误。
你可以使用SET PARSEONLY ON; (或NOEXEC)。 在脚本的末尾使用GO SET PARSEONLY OFF;
SET PARSEONLY ON; -- statement between here will not run SELECT 'THIS WILL NOT EXEC'; GO -- statement below here will run SET PARSEONLY OFF;
尝试将其作为TSQL脚本运行
SELECT 1 RETURN SELECT 2 SELECT 3
返回结束执行。
RETURN(Transact-SQL)
从查询或过程无条件退出。 RETURN是即时且完整的,可以在任何时候使用退出过程,批处理或语句块。 后面的语句不会被执行。
尽pipe它非常明确和强有力的描述,RETURN在存储过程中不适用于我(跳过进一步的执行)。 我不得不修改条件逻辑。 在SQL 2008,2008 R2上都会发生:
create proc dbo.prSess_Ins ( @sSessID varchar( 32 ) , @idSess int out ) as begin set nocount on select @id= idSess from tbSess where sSessID = @sSessID if @idSess > 0 return -- exit sproc here begin tran insert tbSess ( sSessID ) values ( @sSessID ) select @idSess= scope_identity( ) commit end
必须改成:
if @idSess is null begin begin tran insert tbSess ( sSessID ) values ( @sSessID ) select @idSess= scope_identity( ) commit end
作为find重复行的结果而被发现。 debugging打印确认@idSess在IF检查中的值大于零 – RETURN没有中断执行!
通过使用“全局”variables,使用GO批处理可以做到这一点。
if object_id('tempdb..#vars') is not null begin drop table #vars end create table #vars (continueScript bit) set nocount on insert #vars values (1) set nocount off -- Start of first batch if ((select continueScript from #vars)=1) begin print '1' -- Conditionally terminate entire script if (1=1) begin set nocount on update #vars set continueScript=0 set nocount off return end end go -- Start of second batch if ((select continueScript from #vars)=1) begin print '2' end go
对于每个批处理,这里有一个与事务和try / catch块相同的想法。 你可以尝试改变各种条件和/或让它产生一个错误(除以0,见注释)来testing它的行为:
if object_id('tempdb..#vars') is not null begin drop table #vars end create table #vars (continueScript bit) set nocount on insert #vars values (1) set nocount off begin transaction; -- Batch 1 starts here if ((select continueScript from #vars)=1) begin begin try print 'batch 1 starts' if (1=0) begin print 'Script is terminating because of special condition 1.' set nocount on update #vars set continueScript=0 set nocount off return end print 'batch 1 in the middle of its progress' if (1=0) begin print 'Script is terminating because of special condition 2.' set nocount on update #vars set continueScript=0 set nocount off return end set nocount on -- use 1/0 to generate an exception here select 1/1 as test set nocount off end try begin catch set nocount on select error_number() as errornumber ,error_severity() as errorseverity ,error_state() as errorstate ,error_procedure() as errorprocedure ,error_line() as errorline ,error_message() as errormessage; print 'Script is terminating because of error.' update #vars set continueScript=0 set nocount off return end catch; end go -- Batch 2 starts here if ((select continueScript from #vars)=1) begin begin try print 'batch 2 starts' if (1=0) begin print 'Script is terminating because of special condition 1.' set nocount on update #vars set continueScript=0 set nocount off return end print 'batch 2 in the middle of its progress' if (1=0) begin print 'Script is terminating because of special condition 2.' set nocount on update #vars set continueScript=0 set nocount off return end set nocount on -- use 1/0 to generate an exception here select 1/1 as test set nocount off end try begin catch set nocount on select error_number() as errornumber ,error_severity() as errorseverity ,error_state() as errorstate ,error_procedure() as errorprocedure ,error_line() as errorline ,error_message() as errormessage; print 'Script is terminating because of error.' update #vars set continueScript=0 set nocount off return end catch; end go if @@trancount > 0 begin if ((select continueScript from #vars)=1) begin commit transaction print 'transaction committed' end else begin rollback transaction; print 'transaction rolled back' end end
我知道这个问题是古老的,并以几种不同的方式得到了正确的回答,但是在类似的情况下我没有回答这个问题。 第一种方法(非常基本):
IF (1=0) BEGIN PRINT 'it will not go there' -- your script here END PRINT 'but it will here'
第二种方法:
PRINT 'stop here' RETURN -- your script here PRINT 'it will not go there'
你可以自己testing它,以确保它的行为如预期。