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

«Чем хранимая процедура отличается от функции в SQL?» — вопрос из категории Базы данных и SQL, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Хранимые процедуры и функции — это разные программные объекты в SQL, хотя оба хранятся в БД. Их ключевое отличие — в цели использования и способе вызова.

Критерий Хранимая процедура (Stored Procedure) Функция (User-Defined Function, UDF)
Основная цель Выполнить серию действий (логику). Вычислить и вернуть одно значение (скаляр) или таблицу.
Возвращаемое значение Может не возвращать ничего, возвращать несколько результирующих наборов (SELECT) или выходные параметры. Обязана вернуть одно значение (скалярная функция) или таблицу (табличная функция).
Вызов в SQL Специальной инструкцией (CALL ProcName() или EXEC ProcName). Используется внутри SQL-выражения, как встроенная функция: SELECT dbo.CalcTax(price).
Использование в запросах Нельзя использовать прямо в SELECT или WHERE. Прямо используется в SELECT, WHERE, JOIN и т.д.
DML-операции Может выполнять INSERT, UPDATE, DELETE (в большинстве СУБД). Обычно не может модифицировать данные (ограничение в чисто вычислительных функциях).
Транзакции Может управлять транзакциями (BEGIN TRANSACTION, COMMIT). Обычно не управляет транзакциями.

Пример сравнения в T-SQL (MS SQL Server):

-- 1. ХРАНИМАЯ ПРОЦЕДУРА: выполняет действие и возвращает набор данных.
CREATE PROCEDURE GetTopCustomers
AS
BEGIN
    SELECT TOP 10 customer_id, SUM(total) as total_spent 
    FROM orders 
    GROUP BY customer_id 
    ORDER BY total_spent DESC;
END;
-- Вызов:
EXEC GetTopCustomers;

-- 2. ФУНКЦИЯ: вычисляет и возвращает значение для использования в запросе.
CREATE FUNCTION CalculateDiscount(@price DECIMAL(10,2), @rate INT) 
RETURNS DECIMAL(10,2)
AS
BEGIN
    RETURN @price * @rate / 100.0;
END;
-- Использование в выражении:
SELECT product_name, price, 
       dbo.CalculateDiscount(price, 15) as discount_amount -- Вызов функции
FROM products;

Вывод: Используйте процедуру для выполнения логики и действий. Используйте функцию, когда вам нужно результат вычисления подставить в другое SQL-выражение.