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 から入手した例から派生したものです。やみくもにステートメントを実装する前に、T-SQL スクリプトでのフロー制御GOTOに関する彼のチュートリアルを読むことをお勧めします。

于 2012-04-04T04:53:17.197 に答える
41

いいえ、ありません。いくつかのオプションがあります。

  1. スクリプト全体を大きな if/end ブロックでラップします。このブロックは単に true にならないことが保証されています (つまり、「if 1=2 begin」-これは、スクリプトに 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

リターンは実行を終了します。

RETURN(Transact-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 バッチの 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 をデバッグすると、IF チェックで @idSess の値が 0 より大きいことが確認されました - 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'

2 番目のアプローチ:

PRINT 'stop here'
RETURN
    -- your script here
PRINT 'it will not go there'

自分で簡単にテストして、期待どおりに動作することを確認できます。

于 2016-12-08T13:03:09.817 に答える