62

Microsoft SQL Server T-SQL 中是否有命令告诉脚本停止处理?我有一个脚本,我想保留用于存档目的,但我不希望任何人运行它。

4

9 回答 9

57

另一种解决方案可能是通过使用GOTO语句来改变脚本的执行流程......

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语句之前,我建议你阅读他的 T-SQL 脚本中的流控制教程。

于 2012-04-04T04:53:17.197 回答
41

不,没有 - 你有几个选择:

  1. 将整个脚本包装在一个大的 if/end 块中,该块只是确保不为真(即“如果 1=2 开始” - 这仅在脚本不包含任何 GO 语句时才有效(因为那些表示新的批)

  2. 在顶部使用 return 语句(同样,受批处理分隔符的限制)

  3. 使用基于连接的方法,这将确保整个脚本不执行(整个连接更准确) -在脚本顶部使用“SET PARSEONLY ON”“SET NOEXEC ON”之类的东西。这将确保连接中的所有语句(或直到关闭所述 set 语句)都不会执行,而只会被解析/编译。

  4. 使用注释块注释掉整个脚本(即 /* 和 */)

编辑:证明“return”语句是特定于批次的 - 请注意,返回后您将继续看到结果集:

select 1
return
go
select 2
return
select 3
go
select 4
return
select 5
select 6
go
于 2010-01-08T14:19:24.973 回答
20

为什么不简单地将以下内容添加到脚本的开头

PRINT 'INACTIVE SCRIPT'
RETURN
于 2010-01-08T14:15:01.853 回答
19

要解决 RETURN/GO 问题,您可以放在RAISERROR ('Oi! Stop!', 20, 1) WITH LOG顶部。

这将按照MSDN 上的 RAISERROR关闭客户端连接。

最大的缺点是您必须是系统管理员才能使用严重性 20。

编辑:

一个简单的演示来反驳 Jersey Dude 的评论......

RAISERROR ('Oi! Stop!', 20, 1)  WITH LOG
SELECT 'Will not run'
GO
SELECT 'Will not run'
GO
SELECT 'Will not run'
GO
于 2010-01-08T14:16:00.660 回答
9

严重性为 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;
于 2012-03-22T04:40:30.203 回答
4

尝试将其作为 TSQL 脚本运行

SELECT 1
RETURN
SELECT 2
SELECT 3

返回结束执行。

返回(事务处理 SQL)

从查询或过程中无条件退出。RETURN 是立即且完整的,可在任何时候用于退出过程、批处理或语句块。RETURN 后面的语句不会被执行。

于 2010-01-08T14:15:09.840 回答
4

通过使用“全局”变量,这是一种适用于 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

这是用于每个 GO-batch 的事务和 try/catch 块的相同想法。您可以尝试更改各种条件和/或让它生成错误(除以 0,请参阅注释)以测试其行为方式:

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
于 2015-03-18T16:32:35.240 回答
3

尽管它的描述非常明确和有力,但 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

由于查找重复行而发现。调试 PRINT 确认 @idSess 在 IF 检查中的值大于零 - RETURN 没有中断执行!

于 2011-06-17T20:34:47.807 回答
3

我知道这个问题很老,并且以几种不同的方式得到了正确的回答,但是没有像我在类似情况下使用过的答案。第一种方法(非常基本):

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'

您可以自己轻松地对其进行测试,以确保其行为符合预期。

于 2016-12-08T13:03:09.817 回答