Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Вопрос про EXCEPTION WHEN  [new]
person1534
Member

Откуда:
Сообщений: 23
Здравствуйте, товарищи :)

Пишу я функцию

CREATE FUNCTION
DECLARE
BEGIN

SELECT /* Can throw "no data found" */

SELECT

RETURN

EXCEPTION WHEN OTHERS THEN

RETURN NULL

END

При попытке вызвать функцию из view тот ругается, что на 5 строке блока операторов инициируется транзакция.

Поскольку никакой транзакции нет, то складывается ощущение, что эта чудесная калька из Oracle, которая EXCEPTION WHEN, подразумевает использование только в транцакционном коде. Т.е. при ее наличии инициируется транзакция, надо оно или не надо.

Все так?

Заранее спасибо!

С уважением

Сообщение было отредактировано: 16 июл 20, 10:55
16 июл 20, 10:57    [22168399]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про EXCEPTION WHEN  [new]
Павел Лузанов
Member

Откуда:
Сообщений: 722
person1534,

Добавление EXCEPTION в plpgsql блок равносильно установке точки сохранения(SAVEPOINT) сразу после BEGIN. А при попадание в EXCEPTION автоматически выполняется ROLLBACK TO SAVEPOINT. Точки сохранения реализованы как вложенные транзакции (subtransactions). Так что транзакция всё-таки есть.

А покажите как вы получаете ошибку при вызове из view? Мой простой пример ошибки не дает:
postgres=# create or replace function f() returns int 
    as $$declare l int; begin select 1 into strict l from pg_class where 1=0; return 2; exception when others then return null; end;$$ 
language plpgsql;
CREATE FUNCTION
postgres=# create view v as select * from f();
CREATE VIEW
postgres=# select * from v;
 f 
---
  
(1 row)
16 июл 20, 11:27    [22168429]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про EXCEPTION WHEN  [new]
person1534
Member

Откуда:
Сообщений: 23
Здравствуйте, Павел Лузанов


CREATE VIEW
AS
SELECT
A,
FUNCTION(B,C) AS D
FROM
MY_BELOVED_TABLE

Ничего криминального, как мне кажется.

Встречный вопрос, а что, в не-транзакционном коде обработка ошибок не нужна?

Мне, как это, ни BEGIN TRANSACTION, ни SAVEPOINT, рождающиеся сами по себе, не нужны. Я больше привык сам управлять транзакциями, как это в нормальных БД происходит, без AUTOCOMMIT :)


С уважением

Сообщение было отредактировано: 16 июл 20, 11:44
16 июл 20, 11:40    [22168439]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про EXCEPTION WHEN  [new]
Павел Лузанов
Member

Откуда:
Сообщений: 722
person1534,

Сделали как автоматическую защиту. Если попали в EXCEPTION, то можно не сомневаться - любые изменения в основном блоке будут отменены.

Но зная такую особенность plpgsql к обработке ошибок нужно подходить более осознанно. Например, деление на 0 наверное можно и без EXCEPTION проверить.
16 июл 20, 11:48    [22168455]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про EXCEPTION WHEN  [new]
person1534
Member

Откуда:
Сообщений: 23
Знаете, Павел Лузанов,


Я достаточно осознанно пишу код :)

Мне наблюдаемое кажется ошибкой уровня бага. Неудачная и кривая попытка воспроизвести бихевиоры Oracle PL/SQL.

Тем не менее, спасибо за комментарии.


С уважением
16 июл 20, 11:56    [22168464]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про EXCEPTION WHEN  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 1122
person1534
Поскольку никакой транзакции нет

Транзакция есть. Вызова функции вне транзакции не бывает.
16 июл 20, 12:04    [22168474]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про EXCEPTION WHEN  [new]
Павел Лузанов
Member

Откуда:
Сообщений: 722
person1534
Неудачная и кривая попытка воспроизвести бихевиоры Oracle PL/SQL.

Как по мне, отличия от Oracle PL/SQL существенные.
- Вы не можете явно начинать и/или завершать транзакцию внутри функции (BEGIN TRANSACTION/COMMIT). Если не брать процедуры, то это всегда где-то снаружи в клиентском коде происходит.
- Добавление EXCEPTION автоматом добавляет SAVEPOINT в начало блока.
- Попадание в EXCEPTION автоматом выполняет ROLLBACK TO SAVEPOINT. Если есть что откатывать - это удобно, если нет - напрасное расходование ресурсов.

В PL/SQL это всё не так.
Хорошо ли это или плохо? Здесь могут быть разные мнения, ибо у обоих подходов есть достоинства и недостатки.
16 июл 20, 12:24    [22168499]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить