← К оглавлению занятия

🏠 Домашнее задание

📁 Блок: SQL / MySQL / Хранимые процедуры ⏱️ Время изучения: ~90 мин 🎯 Сложность: Продвинутая

⚡ Кратко: 🏠 домашнее задание

Параметры процедуры позволяют передавать данные в процедуру и получать результат обратно.

IN используется для входных значений: процедура читает аргумент и строит по нему запрос.

OUT используется для результата: процедура записывает значение в переменную вызывающего кода через SELECT ... INTO или SET.

INOUT совмещает оба направления: начальное значение приходит в процедуру, изменённое значение возвращается наружу.

Для OUT и INOUT в MySQL обычно передают пользовательские переменные вида @salary.

Минимальный пример: CALL get_employee_salary(1, @salary); SELECT @salary;.

Топ-3 ошибки: вызвать процедуру без CALL, передать литерал вместо переменной в OUT, забыть присвоить значение выходному параметру внутри процедуры.

Домашнее задание из источника

  1. Выведите id департамента, в котором работает сотрудник, в зависимости от id сотрудника.
  2. Создайте хранимую процедуру get_employee_age, которая принимает id сотрудника как IN и возвращает возраст через OUT.
  3. Создайте процедуру decrease_salary, которая принимает зарплату сотрудника как INOUT и уменьшает её на 10%.

Подготовка окружения

DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    age INT,
    salary DECIMAL(10, 2),
    department_id INT
);

INSERT INTO employees (id, name, age, salary, department_id) VALUES
    (1, 'Anna', 28, 5000.00, 10),
    (2, 'Ben', 34, 4200.00, 20),
    (3, 'Cara', 41, 6100.00, 10);

Пошаговое решение

DELIMITER $$

CREATE PROCEDURE get_employee_department(IN emp_id INT)
BEGIN
    SELECT department_id
    FROM employees
    WHERE id = emp_id;
END $$

CREATE PROCEDURE get_employee_age(IN emp_id INT, OUT emp_age INT)
BEGIN
    SELECT age
    INTO emp_age
    FROM employees
    WHERE id = emp_id;
END $$

CREATE PROCEDURE decrease_salary(INOUT emp_salary DECIMAL(10, 2))
BEGIN
    SET emp_salary = emp_salary * 0.90;
END $$

DELIMITER ;

CALL get_employee_department(1);

SET @age = 0;
CALL get_employee_age(2, @age);
SELECT @age;

SET @salary = 5000.00;
CALL decrease_salary(@salary);
SELECT @salary;

Проверка: первый вызов возвращает департамент сотрудника, второй кладёт возраст в @age, третий уменьшает значение @salary до 4500.00.