När felet inträffar återställs transaktionen automatiskt och den aktuella batchen avbryts.
Utförandet fortsätter dock in i nästa batch. Så alla grejer i batcherna efter felet exekveras. Och sedan när du letar efter fel senare, försöker du återställa en redan återställd transaktion.
För att stoppa hela skriptet, inte bara den aktuella batchen, bör du använda:
raiserror('Error description here', 20, -1) with log
Se mitt svar här för detaljer om den.
Så du måste leta efter @error
efter varje batch tror jag att något sånt här borde fungera:
BEGIN TRANSACTION
GO
ALTER Stuff
GO
if @@error != 0 raiserror('Script failed', 20, -1) with log
GO
CREATE New Stuff
GO
if @@error != 0 raiserror('Script failed', 20, -1) with log
GO
DROP Old Stuff
GO
if @@error != 0 raiserror('Script failed', 20, -1) with log
GO
PRINT 'No Errors ... Committing changes'
COMMIT TRANSACTION