CREATE TABLE notary_bonus (
id_bonus INT AUTO_INCREMENT PRIMARY KEY,
id_notary INT NOT NULL,
bonus_month DATE NOT NULL,
bonus_amount DECIMAL(10,2),
FOREIGN KEY (id_notary) REFERENCES notary(id_notary)
);
DELIMITER $$
CREATE PROCEDURE имя_процедуры (
IN параметр1 ТИП,
IN параметр2 ТИП,
...
)
BEGIN
DECLARE переменные ТИП;
DECLARE EXIT HANDLER FOR SQLEXCEPTION ...
START TRANSACTION;
-- Логика процедуры
COMMIT;
END$$
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE calculate_bonuses (
IN p_month DATE
)
BEGIN
DECLARE v_id_notary INT;
DECLARE v_notary_count INT;
DECLARE v_total_comm DECIMAL(10,2);
DECLARE v_bonus DECIMAL(10,2);
DECLARE done INT DEFAULT 0;
DECLARE cur_notary CURSOR FOR SELECT id_notary FROM notary;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
START TRANSACTION;
OPEN cur_notary;
read_loop: LOOP
FETCH cur_notary INTO v_id_notary;
IF done THEN LEAVE read_loop; END IF;
SELECT COUNT(*), SUM(comm) INTO v_notary_count, v_total_comm
FROM deal
WHERE id_notary = v_id_notary
AND deal_data >= DATE_FORMAT(p_month, '%Y-%m-01')
AND deal_data < DATE_ADD(DATE_FORMAT(p_month, '%Y-%m-01'), INTERVAL 1 MONTH);
IF v_notary_count > 100 THEN
SET v_bonus = v_total_comm * 0.10;
ELSEIF v_notary_count > 50 THEN
SET v_bonus = v_total_comm * 0.05;
ELSE
SET v_bonus = 0;
END IF;
INSERT INTO notary_bonus (id_notary, bonus_month, bonus_amount)
VALUES (v_id_notary, DATE_FORMAT(p_month, '%Y-%m-01'), v_bonus)
ON DUPLICATE KEY UPDATE bonus_amount = v_bonus;
END LOOP;
COMMIT;
CLOSE cur_notary;
END$$
DELIMITER ;
Объявление переменных для хранения промежуточных данных.
Перебор строк таблицы notary
для обработки каждого нотариуса.
Начало транзакции для обеспечения целостности данных.
Обновление бонуса, если запись уже существует.
Форматирование даты для фильтрации сделок за месяц.
Использование $$
вместо ;
внутри процедуры.
CALL calculate_bonuses('2025-03-15');
SELECT * FROM notary_bonus;
Ошибка | Причина | Решение |
---|---|---|
Error 1442 |
Обновление таблицы в триггере | Используйте BEFORE INSERT для изменения полей, а не вставку новой строки |
Error 1064 |
Некорректный синтаксис | Убедитесь, что все операторы заканчиваются на ; , а не $$ |
Error 1215 |
Ошибка связи таблиц | Проверьте, что внешние ключи корректны |
-- 1. Таблица для бонусов
CREATE TABLE имя_бонусов (
id_bonus INT AUTO_INCREMENT PRIMARY KEY,
id_нотариуса INT NOT NULL,
бонус_месяц DATE NOT NULL,
бонус_сумма DECIMAL(10,2),
FOREIGN KEY (id_нотариуса) REFERENCES notary(id_notary)
);
-- 2. Процедура
DELIMITER $$
CREATE PROCEDURE имя_процедуры (
IN p_параметр DATE
)
BEGIN
DECLARE v_id_notary INT;
DECLARE v_количество INT;
DECLARE v_сумма DECIMAL(10,2);
DECLARE v_бонус DECIMAL(10,2);
DECLARE done INT DEFAULT 0;
DECLARE cur_notary CURSOR FOR SELECT id_notary FROM notary;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
START TRANSACTION;
OPEN cur_notary;
read_loop: LOOP
FETCH cur_notary INTO v_id_notary;
IF done THEN LEAVE read_loop; END IF;
SELECT COUNT(*), SUM(comm) INTO v_количество, v_сумма
FROM deal
WHERE id_notary = v_id_notary
AND deal_data >= DATE_FORMAT(p_параметр, '%Y-%m-01')
AND deal_data < DATE_ADD(DATE_FORMAT(p_параметр, '%Y-%m-01'), INTERVAL 1 MONTH);
IF v_количество > 100 THEN
SET v_бонус = v_сумма * 0.10;
ELSEIF v_количество > 50 THEN
SET v_бонус = v_сумма * 0.05;
ELSE
SET v_бонус = 0;
END IF;
INSERT INTO имя_бонусов (id_нотариуса, бонус_месяц, бонус_сумма)
VALUES (v_id_notary, DATE_FORMAT(p_параметр, '%Y-%m-01'), v_бонус)
ON DUPLICATE KEY UPDATE бонус_сумма = v_бонус;
END LOOP;
COMMIT;
CLOSE cur_notary;
END$$
DELIMITER ;