Входные и выходные параметры процедур и функций

Параметры: входные vs. выходные 🔄

Процедуры и функции — это «чёрные ящики» в SQL. Чтобы они работали эффективно, нужно правильно передавать данные внутрь и получать результаты. Давайте разберёмся, как управлять этим потоком!

Входные параметры (IN) — данные, которые мы передаём в процедуру/функцию.
Выходные параметры (OUT) — результаты, которые возвращаются наружу.

-- Пример процедуры с входным и выходным параметром
CREATE OR REPLACE PROCEDURE calculate_tax(
    IN salary NUMERIC,       -- Входной параметр
    OUT tax NUMERIC          -- Выходной параметр
) AS $$
BEGIN
    tax := salary * 0.13;    -- Рассчитываем налог 13%
END;
$$ LANGUAGE plpgsql;

Функции: возврат значения через RETURN 🎯

Функции обязаны возвращать значение. Для этого используется оператор RETURN.

-- Функция, возвращающая сумму двух чисел
CREATE OR REPLACE FUNCTION add_numbers(
    a INTEGER, 
    b INTEGER
) RETURNS INTEGER AS $$
BEGIN
    RETURN a + b;  -- Явный возврат результата
END;
$$ LANGUAGE plpgsql;

-- Вызов
SELECT add_numbers(5, 3);  -- Вернёт 8

🔥 Важно! В функциях выходные параметры (OUT) используются редко — их заменяет RETURN.


Процедуры: когда OUT побеждает 🏆

Процедуры не возвращают значения через RETURN, зато могут иметь несколько выходных параметров!

-- Процедура с двумя выходными параметрами
CREATE OR REPLACE PROCEDURE get_employee_stats(
    IN emp_id INTEGER,
    OUT name VARCHAR,
    OUT projects_count INTEGER
) AS $$
BEGIN
    SELECT full_name INTO name FROM employees WHERE id = emp_id;
    SELECT COUNT(*) INTO projects_count FROM projects WHERE owner_id = emp_id;
END;
$$ LANGUAGE plpgsql;

-- Вызов
CALL get_employee_stats(1, NULL, NULL);  -- Заполнит выходные параметры

💡 Лайфхак: В PostgreSQL можно опустить NULL при вызове — достаточно CALL get_employee_stats(1).


INOUT: гибридный режим ⚡

Параметр может быть и входным, и выходным одновременно!

-- Функция увеличивает зарплату и возвращает новое значение
CREATE OR REPLACE FUNCTION increase_salary(
    INOUT current_salary NUMERIC,
    IN bonus NUMERIC
) AS $$
BEGIN
    current_salary := current_salary + bonus;
END;
$$ LANGUAGE plpgsql;

-- Вызов
SELECT increase_salary(50000, 10000);  -- Вернёт 60000

Продвинутые техники 🚀

1. Значения по умолчанию

CREATE FUNCTION greet(name VARCHAR DEFAULT 'Гость') 
RETURNS VARCHAR AS $$
BEGIN
    RETURN 'Привет, ' || name || '!';
END;
$$ LANGUAGE plpgsql;

SELECT greet();        -- Привет, Гость!
SELECT greet('Иван');  -- Привет, Иван!

2. Именованные параметры

CREATE FUNCTION create_user(
    login VARCHAR,
    is_admin BOOLEAN DEFAULT FALSE
) RETURNS VOID AS $$
BEGIN
    -- Регистрация пользователя
END;
$$ LANGUAGE plpgsql;

-- Читаемый вызов!
SELECT create_user(login => 'danila', is_admin => TRUE);

Ошибки, которые ломают код 💥

❌ Смешивание RETURN и OUT в функциях

-- Так не делайте!
CREATE FUNCTION confusion() 
RETURNS INTEGER AS $$
DECLARE
    result INTEGER;
BEGIN
    RETURN 42;      -- Возврат через RETURN
    result := 100;  -- Но есть OUT-переменная (ошибка в некоторых СУБД)
END;
$$ LANGUAGE plpgsql;

✅ Правильный подход

CREATE FUNCTION clarity() 
RETURNS INTEGER AS $$
DECLARE
    result INTEGER;
BEGIN
    result := 42;
    RETURN result;  -- Всё прозрачно!
END;
$$ LANGUAGE plpgsql;

Практика: пишем реалистичные примеры 🛠️

Пример 1: Расчёт НДС

CREATE FUNCTION calculate_vat(
    amount NUMERIC,
    vat_rate NUMERIC DEFAULT 0.20
) RETURNS NUMERIC AS $$
BEGIN
    RETURN amount * vat_rate;
END;
$$ LANGUAGE plpgsql;

-- Использование
SELECT amount, calculate_vat(amount) AS vat FROM invoices;

Пример 2: Обновление статуса заказа

CREATE PROCEDURE update_order_status(
    IN order_id INTEGER,
    IN new_status VARCHAR,
    OUT old_status VARCHAR
) AS $$
BEGIN
    SELECT status INTO old_status FROM orders WHERE id = order_id;
    UPDATE orders SET status = new_status WHERE id = order_id;
END;
$$ LANGUAGE plpgsql;

-- Вызов
CALL update_order_status(123, 'shipped', NULL);

Теперь ты мастер параметров! 🎓

Попробуй создать свою процедуру с тремя параметрами: один IN, один OUT и один INOUT. Экспериментируй с разными типами данных — даты, JSON, массивы!

Как говорит Данила Бежин: «Параметры — это мосты между вашим кодом и внешним миром. Стройте их надёжно!» 🌉

👉 Больше практики — на YouTube-канале Данилы.

Скрыть рекламу навсегда

🎥 YouTube: программирование простым языком

Канал, где я спокойно и по шагам объясняю сложные темы — без заумных терминов и лишней теории.

Подходит, если раньше «не заходило», но хочется наконец понять.

▶️ Смотреть курсы на YouTube