Microsoft SQL Server T-SQLに、スクリプトに処理を停止するように指示するコマンドはありますか?アーカイブの目的で保持したいスクリプトがありますが、誰にも実行させたくありません。
9 に答える
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
に関する彼のチュートリアルを読むことをお勧めします。
いいえ、ありません。いくつかのオプションがあります。
スクリプト全体を大きな if/end ブロックでラップします。このブロックは単に true にならないことが保証されています (つまり、「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に従ってクライアント接続が閉じられます。
非常に大きな欠点は、重大度 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
重大度 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 の値が 0 より大きいことが確認されました - 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'
自分で簡単にテストして、期待どおりに動作することを確認できます。