middle
Чем отличаются функции от процедур в PostgreSQL?
Начиная с PostgreSQL 11 поддерживаются как функции (FUNCTION), так и процедуры (PROCEDURE). Ключевое различие: процедуры могут управлять транзакциями (COMMIT/ROLLBACK внутри тела), а функции — нет.
Функции (FUNCTION)
Пример
CREATE OR REPLACE FUNCTION get_account_balance(p_account_id bigint)
RETURNS numeric AS $$
DECLARE
v_balance numeric;
BEGIN
SELECT balance INTO v_balance
FROM accounts WHERE id = p_account_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Счёт % не найден', p_account_id;
END IF;
RETURN v_balance;
END;
$$ LANGUAGE plpgsql;
SELECT get_account_balance(1);
Процедуры (PROCEDURE)
Пример процедуры перевода средств
CREATE OR REPLACE PROCEDURE transfer_funds(
p_from_account bigint,
p_to_account bigint,
p_amount numeric
)
LANGUAGE plpgsql AS $$
BEGIN
IF p_amount <= 0 THEN
RAISE EXCEPTION 'Сумма перевода должна быть положительной';
END IF;
UPDATE accounts SET balance = balance - p_amount WHERE id = p_from_account;
IF NOT FOUND THEN
RAISE EXCEPTION 'Счёт-отправитель % не найден', p_from_account;
END IF;
UPDATE accounts SET balance = balance + p_amount WHERE id = p_to_account;
IF NOT FOUND THEN
RAISE EXCEPTION 'Счёт-получатель % не найден', p_to_account;
END IF;
-- Процедура может управлять транзакциями!
COMMIT;
END;
$$;
CALL transfer_funds(1, 2, 50000);
Ключевые отличия
| Свойство | FUNCTION | PROCEDURE |
|---|---|---|
| Возвращает значение | Да (RETURNS) | Нет |
| Управление транзакциями | Нет (COMMIT/ROLLBACK запрещены) | Да (COMMIT/ROLLBACK разрешены) |
| Использование в SELECT | SELECT func() |
Нет |
| Вызов | SELECT func() или в выражениях |
CALL proc() |
| Используется в триггерах | Да | Нет |
Процедуры полезны для длительных пакетных операций, где нужно промежуточно фиксировать результаты (например, миграция данных большими батчами).
На собеседовании: единственный критический факт — процедуры могут делать COMMIT/ROLLBACK, функции — нет. Это определяет выбор: если нужно промежуточно фиксировать результаты в длительной операции — процедура, если нужно вернуть значение или использовать в SELECT — функция.