views:

476

answers:

5

i have a series of T-SQL statements separated by the special Query Analyzer batch separator keyword:

GO

If one batch fails, i need Query Analyzer to not try subsequent batches - i want it to stop processing the series of batches.

For example:

PRINT 'This runs'
go

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

PRINT 'This should not run'
go

Output:

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

Possible?


Update

An example of this in real use might be:

 sp_rename 'Shelby', 'Kirsten'
 go

 DROP VIEW PeekAView
 go

 CREATE VIEW PeekAViewAS 
 SELECT * FROM Kirsten
 go
+1  A: 

Create a temporary table; and update it after each step (if successful); and then check the success of the previous step by validating against the table.

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
+1. Perhaps there's a better way but this simply is so easy I wonder why I never thought of that.
Lieven
Its more or less how MS do it themselves in the scripting wizard
u07ch
And Red Gate Compare
gbn
+1 This works for me, couldn't deploy without it!
Andomar
This won't work when one of the statements is **CREATE VIEW**
Ian Boyd
You can check for the existence of the view and use that to control the insert into your transaction table
u07ch
What if you're updating an exiting view? Or a function or procedure or trigger?
Philip Kelley
A: 

based on @u07ch idea, but only insert on failure...

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

output 2000:

one
two
three

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

(1 row(s) affected)

ERROR

output 2005/2008:

one
two
three

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

(0 row(s) affected)

(1 row(s) affected)

ERROR
KM
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? can someone tell me why there are so many down votes on this question? get a life, they are only "points" and life will go on with or without them ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
KM
Isn't it obvious? "This question is not useful or clear". /sarcasm
Ian Boyd
and I thought my answer was correct?
KM
<sarcasm>Maybe your answer was too much detailed</sarcasm> Moreover it should also perform better (though slightly) than the original one since it inserts only when there is an error.... Did you flirt with someone's wife, recently? ;-)
Turro
A: 

Erland Sommarskog in the microsoft.public.sqlserver.programming group had a very good idea:

In a change script such as the one you posted, you need to be defensive, and start each batch with IF @@trancount > 0.

Using

IF @@trancount > 0

is much cleaner.

Ian Boyd
This won't for for all batch contents.
Ian Boyd
A: 

You can activate the "Query, SQLCMD Mode" menu option and place the following at the beginning of the script:

:on error exit

This will stop execution when an error occurs, even if there are subsequent batches.

Just make sure that you don't accidentally run the script without SQLCMD mode on because you will get the typical behavior where errors are ignored.

binarycoder
+1  A: 

When I need to do this, I issue a RAISERROR of severity 20. This, or higher, will kill the current connection, and prevent subsequent "GO batches" from executing. Yes, it can be awkward, but it does the job.

Philip Kelley