Что такое хранимая процедура в SQL?

Ответ

Хранимая процедура (Stored Procedure) — это именованный блок SQL-кода, который компилируется и сохраняется на стороне сервера базы данных. Её можно вызывать с параметрами, она может содержать сложную бизнес-логику, включая условия, циклы и транзакции.

Ключевые преимущества:

  • Производительность: План выполнения кэшируется сервером БД, что снижает overhead при повторных вызовах.
  • Снижение сетевого трафика: Вместо отправки нескольких запросов из приложения клиент отправляет один вызов процедуры.
  • Безопасность и абстракция: Можно предоставить приложению права на выполнение процедуры, но не на прямой доступ к таблицам. Это слой абстракции над схемой данных.
  • Централизация логики: Бизнес-правила, реализованные в процедуре, едины для всех приложений, обращающихся к БД.

Пример создания и вызова в PostgreSQL:

-- Создание процедуры для получения заказов клиента и общего чека
CREATE OR REPLACE PROCEDURE get_customer_summary(
    IN cust_id INT,
    OUT order_count INT,
    OUT total_amount DECIMAL
)
LANGUAGE plpgsql
AS $$
BEGIN
    SELECT COUNT(*), SUM(amount)
    INTO order_count, total_amount
    FROM orders
    WHERE customer_id = cust_id;
END;
$$;

-- Вызов процедуры
DO $$
DECLARE
    count INT;
    total DECIMAL;
BEGIN
    CALL get_customer_summary(123, count, total);
    RAISE NOTICE 'Orders: %, Total: %', count, total;
END;
$$;

Недостатки: Перенос логики в БД может усложнить версионирование, тестирование и интеграцию с системами CI/CD. Важно соблюдать баланс между логикой в приложении и логикой в БД.

Ответ 18+ 🔞

Да ты посмотри, что эти умники придумали! Хранимая процедура, блядь. Это типа такой запечатанный кусок SQL-овского кода, который сидит прямо в животе у базы данных, как недопереваренный обед. Назвали его, сохранили на сервере, и теперь можно тыкать в него палкой, вызывать, а он будет выполнять всю ту хуйню, которую в него впихнули: условия, циклы, транзакции — всю эту бизнес-логику, которая обычно в коде приложения размазана.

И в чём же, блядь, её охуенность?

  • Скорость, ёпта! Сервер её один раз прочитал, понял, как её выполнять, и план этот схоронил. При следующем вызове — бац, и уже готово, не надо каждый раз мозги напрягать. Overhead, сука, снижается.
  • Меньше трепа по сети. Вместо того чтобы слать из приложения десять запросов подряд, можно послать один: «Эй, процедура, сделай дело!». И она там на месте всё порешает.
  • Безопасность, абстракция, вот это всё. Можно приложению дать права только на выполнение этой самой процедуры, а к таблицам прямым ходом — хуй вам, а не доступ. Получается такой защитный слой, пизда с ушами, между приложением и голыми данными.
  • Логика в одном месте. Если какое-то бизнес-правило зашито в процедуру, то оно одно для всех. Не будет такого, что одно приложение считает так, а другое — эдак. Централизация, мать её.

Вот, смотри, как это в Постгресе выглядит, чтоб ты понимал масштаб:

-- Создаём процедуру, которая посчитает заказы клиента и общую сумму
CREATE OR REPLACE PROCEDURE get_customer_summary(
    IN cust_id INT,
    OUT order_count INT,
    OUT total_amount DECIMAL
)
LANGUAGE plpgsql
AS $$
BEGIN
    SELECT COUNT(*), SUM(amount)
    INTO order_count, total_amount
    FROM orders
    WHERE customer_id = cust_id;
END;
$$;

-- А вот так её вызываем, чтобы она отработала
DO $$
DECLARE
    count INT;
    total DECIMAL;
BEGIN
    CALL get_customer_summary(123, count, total);
    RAISE NOTICE 'Orders: %, Total: %', count, total;
END;
$$;

Но и минусы, блядь, есть, куда ж без них! Если всю логику перетащить в базу, то потом её версионировать, тестировать и впихивать в эти ваши CI/CD-пайплайны — это ещё та песня, доверия ебать ноль. Получается, надо искать баланс, сука: что-то оставить в приложении, а что-то — в эту самую хранимую процедуру запихнуть. А то получится спагетти-код, только на стороне БД.