Почему mySQL Trigger не сохраняется?

Я пытаюсь создать триггер, который останавливает вставку, если уже были сделаны две вставки с одинаковым «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 ;
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
3
0
415
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы хотите присвоить счет переменной, пока ваш код сравнивает ее. Для этого потребуется использовать объявленную переменную и выбрать ее 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 12.12.2020 23:57

@GašperŠtepec: я только что изменил ответ и добавил скрипт БД.

GMB 13.12.2020 00:02

В триггере 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 ;

(Обратите внимание, что то, как вы присвоили результат переменной, тоже было ошибочным. Но в переменной нет необходимости, вы можете использовать подзапрос непосредственно в сравнении.)

Проверил ваше решение, оно тоже работает. Спасибо!

Gašper Štepec 13.12.2020 13:40

Другие вопросы по теме