Учитывая это:
create table z
(
i int identity(1,1) not null,
zzz int not null
);
При попытке выполнить следующее ..
begin try
begin transaction
alter table z drop column aaa;
commit tran;
end try
begin catch
print 'hello';
SELECT
ERROR_NUMBER() as ErrorNumber,
ERROR_MESSAGE() as ErrorMessage;
IF (XACT_STATE()) = -1
BEGIN
PRINT
N'The transaction is in an uncommittable state. ' +
'Rolling back transaction.'
ROLLBACK TRANSACTION;
END;
end catch
print 'reached';
.. ошибка может быть поймана:
ErrorNumber ErrorMessage
4924 ALTER TABLE DROP COLUMN failed because column 'aaa' does not exist in table 'z'.
Но попробуйте изменить alter table z drop column aaa;
на alter table z add zzz int;
, Sql Server может перехватить ошибку ..
Имена столбцов в каждой таблице должны быть уникальными. Название столбца 'zzz' в таблице
'z' указано более одного раза.
.. но вам не удастся вернуть управление, блок CATCH не сработает. Кажется, нет жестких и быстрых правил, какие ошибки можно отследить, а какие нет.
Чтобы проиллюстрировать разницу, вот код, который можно отследить по вашему коду

Вот ошибка, которую ваш код не может отловить, что похоже на вашу проблему.

Обратите внимание, что там нет сетки (через SELECT ERROR_NUMBER() as ErrorNumber, ERROR_MESSAGE() as ErrorMessage;
). Это означает, что Sql Server не вернул вам элемент управления после обнаружения исключения.
Возможно, здесь вы найдете другие подробности, которые могут помочь: http://msdn.microsoft.com/en-us/library/ms179296.aspx
См. Данное руководство по обработке ошибок @@ ERROR и / или TRY - CATCH
<Ч />
Кстати, в Postgresql все виды ошибок DDL распознаются вашим кодом.
do $$
begin
-- alter table z drop column aaa;
alter table z add zzz int;
exception when others then
raise notice 'The transaction is in an uncommittable state. '
'Transaction was rolled back';
raise notice 'Yo this is good! --> % %', SQLERRM, SQLSTATE;
end;
$$ language 'plpgsql';
Вот сообщение об ошибке от разработчика для alter table z drop column aaa;
в Postgresql:

Вот сообщение об ошибке от разработчика для alter table z add zzz int;
в Postgresql; который, кстати, в Sql Server, когда он имеет ошибку в операторе такого типа, не вернет вам управление, поэтому ваши CATCH
разделы иногда полезны, иногда бесполезны.
