Ich habe die noexec on/off-Lösung erfolgreich mit einer Transaktion erweitert, um das Skript in einer Alles-oder-Nichts-Weise auszuführen.
set noexec off
begin transaction
go
<First batch, do something here>
go
if @@error != 0 set noexec on;
<Second batch, do something here>
go
if @@error != 0 set noexec on;
<... etc>
declare @finished bit;
set @finished = 1;
SET noexec off;
IF @finished = 1
BEGIN
PRINT 'Committing changes'
COMMIT TRANSACTION
END
ELSE
BEGIN
PRINT 'Errors occured. Rolling back changes'
ROLLBACK TRANSACTION
END
Offenbar "versteht" der Compiler die @finished-Variable in der IF, auch wenn ein Fehler aufgetreten ist und die Ausführung deaktiviert wurde. Der Wert wird jedoch nur dann auf 1 gesetzt, wenn die Ausführung nicht deaktiviert wurde. Daher kann ich die Transaktion entsprechend festschreiben oder zurücksetzen.