質問

特別なクエリアナライザーバッチセパレーターキーワードで区切られた一連のT-SQLステートメントがあります。

GO

1つのバッチが失敗した場合、後続のバッチを試しないようにクエリアナライザーが必要です。一連のバッチの処理を停止する必要があります。

例えば:

PRINT 'This runs'
go

SELECT 0/0, 'This causes an error'
go

PRINT 'This should not run'
go

出力:

This runs
Server: Msg 8134, Level 16, State 1, Line 2
Divide by zero error encountered.
This should not run

可能?


アップデート

実際の使用の例は次のとおりです。

 sp_rename 'Shelby', 'Kirsten'
 go

 DROP VIEW PeekAView
 go

 CREATE VIEW PeekAViewAS 
 SELECT * FROM Kirsten
 go
役に立ちましたか?

解決

これが私がそれをする方法です:

PRINT 'This runs'
go

SELECT 0/0, 'This causes an error'
go
if (@@error <> 0)
    Begin
    set nocount on
    set noexec on
    End
GO

PRINT 'This should not run'
go

set noexec off
set nocount off
GO

「NOEXEC」モードは、SSMSを配置することは、T-SQLをコンパイルするだけで実際に実行しない状態です。実行(F5)の代わりに、誤って解析ツールバーボタン(CTRL+F5)を押すことに似ています。

スクリプトの最後にNOEXECをオフにすることを忘れないでください。それ以外の場合は、ユーザーは永続的な「コマンドが正常に完了した」と混乱します。メッセージ。

トライキャッチブロックを使用する代わりに、後続のバッチで@@エラーに対するチェックを使用します。次のバッチで@@エラーを使用すると、「テーブルは存在しない」などのコンパイルエラーがキャッチされます。

NOEXECモードに加えて、NoCountモードも切り替えます。 NOEXECモードをオンにしてオフにした場合、クエリは引き続きメッセージ「(0行の影響を受けた)」というメッセージを報告します。メッセージは、NOEXECモードにあるため、常にゼロ行を報告します。ただし、nocountを回すとこれらのメッセージが抑制されます。

また、SQL Server 2005を実行している場合、スキップしているコマンドが存在しないテーブルとバッチの最初のコマンドの場合はコマンドを参照する場合、エラーメッセージが表示される場合があります。コマンドを偽の印刷ステートメントでバッチ内の2番目のコマンドにすることを強制することで、これを抑制できます。見る MSバグ#569263 詳細については。

他のヒント

「クエリ、SQLCMDモード」メニューオプションをアクティブにして、スクリプトの先頭に次のことを配置できます。

:on error exit

これにより、後続のバッチがある場合でも、エラーが発生したときに実行が停止します。

エラーが無視されている典型的な動作が得られるため、sqlcmdモードをオンにしないと、誤ってスクリプトを実行しないようにしてください。

これを行う必要があるとき、私は重大度20のレイゼローを発行します。はい、それは厄介ですが、それは仕事をします。

一時テーブルを作成します。各ステップの後に更新します(成功した場合)。そして、テーブルに対して検証して、前のステップの成功を確認します。

create table #ScriptChecker (SuccessfullStep int)

-- Do Step One
Insert into #ScriptChecker
Select 1

-- Step 2
If exists (select * from #ScriptChecker where SuccessfullStep = 1)
-- Do Step 2 ...

@u07chのアイデアに基づいていますが、失敗にのみ挿入してください...

create table #test (failure  int)

if not exists (select * from #test)
BEGIN
    print 'one' --sql here
END
go

if not exists (select * from #test)
BEGIN
    print 'two'--sql here
END
go

if not exists (select * from #test)
BEGIN
    print 'three' ---SQL SERVER 2000 version
    --error--
    SELECT 0/0, 'This causes an error'
    IF @@ERROR!=0
    BEGIN
        insert into #test values (1)
        PRINT 'ERROR'
    END
end 
go

if not exists (select * from #test)
BEGIN
    print 'three'  ---SQL SERVER 2005/2008 version
    BEGIN TRY
    --error--
        SELECT 0/0, 'This causes an error'
    END TRY
    BEGIN CATCH
        insert into #test values (1)
        PRINT 'ERROR'
    END CATCH
END
go

if not exists (select * from #test)
BEGIN
    --sql here
    print 'four'
END
go

出力2000:

one
two
three

----------- --------------------
Msg 8134, Level 16, State 1, Line 7
Divide by zero error encountered.

(1 row(s) affected)

ERROR

出力2005/2008:

one
two
three

----------- --------------------

(0 row(s) affected)

(1 row(s) affected)

ERROR

Microsoft.public.sqlserver.programmingグループのErland sommarskogは非常に良いアイデアを持っていました。

投稿したような変更スクリプトでは、防御的である必要があり、@@ trancount> 0の場合は各バッチを開始する必要があります。

使用

IF @@trancount > 0 

もっときれいです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top