Я пытаюсь создать триггер, который останавливает вставку, если уже были сделаны две вставки с одинаковым «St_Obr». Он не показывает ошибок, но когда я запускаю скрипт SQL, триггер не сохраняется. По крайней мере, это не отображается, когда я запускаю SHOW TRIGGERS;
Код:
DELIMITER //
CREATE TRIGGER ob_limit
BEFORE INSERT ON TUP.Lab FOR EACH ROW
BEGIN
SELECT @a = COUNT(*)
FROM TUP.Lab
WHERE St_Obr = NEW.St_Obr;
IF (@a > 2) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'MAX 2!';
END IF;
END //
DELIMITER ;
Вы хотите присвоить счет переменной, пока ваш код сравнивает ее. Для этого потребуется использовать объявленную переменную и выбрать ее into
.
Но я считаю, что проще пропустить переменную и запустить запрос непосредственно в операторе if
:
CREATE TRIGGER ob_limit
BEFORE INSERT ON Lab FOR EACH ROW
BEGIN
IF ((SELECT COUNT(*) FROM Lab WHERE St_Obr = NEW.St_Obr) >= 2) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'MAX 2!';
END IF;
END //
DELIMITER ;
Обратите внимание, что я изменил неравенство с >
на >=2
: первое допускает три строки на St_Obr
, а второе — только 2 (это то, что вы, кажется, хотите).
Вот Демо на DB Fiddle; вы можете прокомментировать или раскомментировать третий insert
, чтобы сгенерировать ошибку.
@GašperŠtepec: я только что изменил ответ и добавил скрипт БД.
В триггере BEFORE
вставленная строка не может быть «увидена» оператором SELECT count(*) ...
в триггере. Он выполняется до того, как новая строка будет вставлена в таблицу. Вы можете уменьшить лимит до 1
или использовать >=
, как предлагает GMB. Или вы можете изменить триггер на триггер AFTER
.
CREATE TRIGGER ob_limit
AFTER INSERT ON Lab
FOR EACH ROW
BEGIN
IF (SELECT count(*)
FROM Lab
WHERE st_obr = new.st_obr) > 2 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'MAX 2!';
END IF;
END //
DELIMITER ;
(Обратите внимание, что то, как вы присвоили результат переменной, тоже было ошибочным. Но в переменной нет необходимости, вы можете использовать подзапрос непосредственно в сравнении.)
Проверил ваше решение, оно тоже работает. Спасибо!
Спасибо за ваше исправление, но триггер по-прежнему не отображается после его выполнения.