Обработка любой ошибки в процедуре

Дмитрий Голубев
Дата: 10.11.2004 10:59:40
Привет всем.

Вопрос такой есть ли в Постгре какойто обработчик любой ошибки (нет реляции, поле нот нулл и т.п.). Тоесть мне надо, чтобы при возникновении ошибки при выполнении запроса в процедуре, я мог обработать ошибку, откатить транзакцию и выйти из процедуры с возвращением из нее нужного мне значения.

Вопрос - можноли сделать так, чтобы при возникновении ошибки процедура не вываливалась с ексептионом "произошла какаято беда", а возвращала например красивое значение -1 .

-----------------------------------------------------------------------
На MSSQL я делал следующим образом:
@@ERROR - системная переменая, которая содержит код ошибки при возникновении какой либо ошибки в вышеописаном запросе.

BEGIN TRANSACTION 
	INSERT INTO tbTest ( Field )
	VALUES ( 1 )

	IF ( @@ERROR != 0 ) GOTO Label_ExitWithRollback 

COMMIT TRANSACTION

RETURN 1

----------------------------------------------------------------------	
--> Labels --
Label_ExitWithRollback:
IF ( @@TRANCOUNT > 0 ) ROLLBACK TRANSACTION 

RETURN -1
-- Labels <--

Воможно я смотрю на данную тему с привычной мне колокольни, если так то подскажите пути решения.

Всем спасибо
4321
Дата: 10.11.2004 12:17:24

PostgreSQL does not have a very smart exception handling model. Whenever the parser, planner/optimizer or executor decide that a statement cannot be processed any longer, the whole transaction gets aborted and the system jumps back into the main loop to get the next command from the client application.

It is possible to hook into the error mechanism to notice that this happens. But currently it is impossible to tell what really caused the abort (data type format error, floating-point error, parse error, etc.). And it is possible that the database server is in an inconsistent state at this point so returning to the upper executor or issuing more commands might corrupt the whole database.

Thus, the only thing PL/pgSQL currently does when it encounters an abort during execution of a function or trigger procedure is to add some fields to the message telling in which function and where (line number and type of statement) the error happened. The error always stops execution of the function.
фффф
Дата: 10.11.2004 12:46:32
В версии 8.0 в pl/pgsql добавили возможность перехвата исключений по образцу Oracle:
Chapter 35. PL/pgSQL - SQL Procedural Language
35.6. Basic Statements

BEGIN
  y := x / 0;
EXCEPTION
  WHEN division_by_zero THEN
     NULL;  -- ignore the error
END;
4321
Дата: 12.11.2004 11:27:09
2фффф
фффф
В версии 8.0 в pl/pgsql добавили возможность перехвата исключений
уже радует. Сенькс.

А как насчет updatable cursor ? Уже есть? А то в Unsupported Features для PostgreSQL 7.4beta4 Documentation видим:
F831        Full cursor update   
F831-01   Updatable scrollable cursors   
F831-02   Updatable ordered cursors   

- т.ч. не очень даже и понятно, накера тогда курсоры открывать. (опять же вразумительный поиск по условию в курсорах я не обнаружил - видимо самому предлагается поиск посредством полного скролирования осуществлять?). Это, впрочем, может статься и к лучшему - меньше соблазнов уклониться от лобового юзанья SQL.

Или я чего-то, как обычно, не догоняю?
hastler
Дата: 17.11.2004 20:01:02
фффф
В версии 8.0 в pl/pgsql добавили возможность перехвата исключений по образцу Oracle:


Ага, только использовать неполучается - сильно тормозит :(
ilejn
Дата: 18.11.2004 10:04:03
hastler
фффф
В версии 8.0 в pl/pgsql добавили возможность перехвата исключений по образцу Oracle:


Ага, только использовать неполучается - сильно тормозит :(


Чуть подробнее, если можно.

Тормозит всегда, или только при генерации исключения, нужны ли какие-то
особые причины для торможения, типа большого уровня вложенности или
очень длинной транзакции?
hastler
Дата: 23.11.2004 13:11:25
У меня процедура в цикле выполняется. Так вот, при добавлении EXCEPTION скорость работы уменьшается в ~10 раз, вне зависимости срабатывает исключение или нет. Я так понимаю, это что-то вроде вложенной транзакции, запуск которой и кушет время.

Однако, остается надежда что в релизе ситуация улучшится :)