Gdy wystąpi błąd, transakcja zostanie automatycznie wycofana, a bieżąca partia zostanie przerwana.
Egzekucja trwa jednak do następnej partii. Więc wszystkie rzeczy w partiach po wykonaniu błędu. A potem, gdy później sprawdzisz błędy, spróbujesz wycofać już wycofaną transakcję.
Ponadto, aby zatrzymać cały skrypt, a nie tylko bieżącą partię, powinieneś użyć:
raiserror('Error description here', 20, -1) with log
Zobacz moja odpowiedź tutaj aby uzyskać szczegółowe informacje na ten temat.
Musisz więc sprawdzić @error
po każdej partii myślę, że coś takiego powinno działać:
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