スクリプトに処理を停止するように指示するコマンドがMicrosoft SQL Server T-SQLにありますか?アーカイブの目的で保持したいスクリプトがありますが、誰にも実行させたくありません。
別の解決策は、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スクリプトのフロー制御 に関するチュートリアルを読むことをお勧めします。
いいえ、ありません-いくつかのオプションがあります:
単純に真ではないことが保証されている大きなif/endブロックでスクリプト全体をラップします(つまり、「if 1 = 2 begin」-ただし、スクリプトにGOステートメントが含まれていない場合にのみ機能します(新しいバッチ)
上部のreturnステートメントを使用します(これもバッチセパレーターによって制限されます)
接続ベースのアプローチを使用します。これにより、スクリプト全体が非実行になります(接続全体がより正確になります)。 'SET PARSEONLY ON' または 'SET NOEXEC ON ' スクリプトの上部。これにより、接続内のすべてのステートメントが(または、前述のsetステートメントがオフになるまで)実行されず、代わりに解析/コンパイルのみが実行されます。
コメントブロックを使用して、スクリプト全体をコメントアウトします(つまり、/ *および* /)
編集:「return」ステートメントがバッチ固有であることのデモンストレーション-リターン後も引き続き結果セットが表示されることに注意してください。
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のRAISERROR に従ってクライアント接続が閉じられます。
非常にbigマイナス面は、重大度20を使用するにはsysadminである必要があるということです。
編集:
Jersey Dudeのコメントに対抗する簡単なデモ...
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は即時かつ完全であり、プロシージャ、バッチ、またはステートメントブロックを終了するためにいつでも使用できます。 RETURNに続くステートメントは実行されません。
「グローバル」変数を使用して、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
非常に明示的かつ強制的な説明にもかかわらず、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の値がゼロよりも大きいことが確認されました-RETURNは実行を中断しませんでした!
私は質問が古く、いくつかの異なる方法で正しく答えられたことを知っていますが、私が同じような状況で使用した私の答えはありません。最初のアプローチ(非常に基本的な):
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'
自分で簡単にテストして、期待どおりに動作することを確認できます。