MySQL Trigger для предотвращения INSERT при определенных условиях - PullRequest
29 голосов
/ 06 июня 2010

Я хочу сделать триггер, который предотвратит вставку, если дата рождения (один из столбцов) будет в будущем У меня есть это:

CREATE TRIGGER foo
BEFORE INSERT ON table
FOR EACH ROW
BEGIN
  IF NEW.birthdate > CURRENT_DATE()
  THEN
    //How do I prevent the insert right here???
  END IF;
END;

Как я могу отменить вставку внутри оператора if?

Ответы [ 6 ]

43 голосов
/ 18 марта 2014

Пример 1, MySQL, Вы можете отменить эту вставку в триггере с помощью signal sqlstate

  1. Создайте свою таблицу с колонкой varchar:

    mysql> create table yar (val VARCHAR(25) not null);
    Query OK, 0 rows affected (0.02 sec)
    
  2. Создайте триггер «перед вставкой» для проверки состояния и запрета.

    mysql> delimiter $$
    mysql> create trigger foo before insert on yar
        -> for each row
        -> begin
        -> if new.val = '' then
        -> signal sqlstate '45000';
        -> end if;
        -> end;$$
    Query OK, 0 rows affected (0.01 sec)
    
  3. Попробуйте указать, где выполняется условие:

    mysql> delimiter ;
    
    mysql> insert into yar values("");
    ERROR 1644 (45000): Unhandled user-defined exception condition
    
    mysql> insert into yar values ("abc");
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from yar;
    +-----+
    | val |
    +-----+
    | abc |
    +-----+
    1 row in set (0.00 sec)
    

Вы вставили пустую строку, триггер увидел, что она пуста, и поднял сигнал, чтобы предотвратить вставку.

Пример 2, MySQL, отмените вставку в триггер, вызвав нарушение данных ненулевым ограничением.

  1. Создайте свою таблицу с колонкой varchar:

    mysql> create table yar (val VARCHAR(25) not null);
    Query OK, 0 rows affected (0.02 sec)
    
  2. Создайте триггер «перед вставкой» для проверки состояния и запрета.

    mysql> delimiter $$
    mysql> create trigger foo before insert on yar
        -> for each row
        -> begin
        -> if new.val = '' then
        -> set new.val = NULL;
        -> end if;
        -> end;$$
    Query OK, 0 rows affected (0.01 sec)
    
  3. Попробуйте указать, где выполняется условие:

    mysql> delimiter ;
    
    mysql> insert into yar values("");
    ERROR 1048 (23000): Column 'val' cannot be null
    
    mysql> insert into yar values ("abc");
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from yar;
    +-----+
    | val |
    +-----+
    | abc |
    +-----+
    1 row in set (0.00 sec)
    

Вы вставили пустую строку, триггер увидел, что она пустая, и изменил значение на ноль, поэтому вставка запрещена.

11 голосов
/ 24 июля 2015

Не знаю, поздно ли, но вы можете сделать это сейчас:

SIGNAL SQLSTATE '45000' 
SET MESSAGE_TEXT = "your error text";

P.S. Не забудьте изменить разделитель до и после триггера ...

7 голосов
/ 06 июня 2010

На основании это Я не уверен, что это можно сделать таким образом.

Там нет поддержки в текущем MySQL реализация триггеров для добровольно бросить исключение и прервать утверждение, которое породило спусковой крючок.

Обходной путь, который я нашел, это написать ДО триггера, чтобы установить один из не-NULL столбцы в таблице в NULL, таким образом нарушая его НЕ NULL ограничение. Это вызывает утверждение что породило триггер прерванный.

3 голосов
/ 26 июня 2017
DELIMITER $$
CREATE TRIGGER foo
BEFORE INSERT ON table
FOR EACH ROW
BEGIN
  IF NEW.birthdate > CURRENT_DATE()
  THEN
   SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Warning: birthdate can not be greater than current date!';
  END IF;

END$$
    DELIMITER ;
0 голосов
/ 21 февраля 2013

У меня была такая же проблема. Я создал таблицу, но не было никакого способа назначить минимальную длину строки в MySQL. Я создал таблицу следующим образом:

CREATE TABLE Users
           (
             UserName varchar(15) NOT NULL PRIMARY KEY,
             Password varchar(15) NOT NULL,
             Active Bool DEFAULT TRUE,
             CHECK (CHAR_LENGTH(UserName)>3)
           )

Но функция CHECK не работает при вставке.

Итак, я изменил свою таблицу следующим образом:

CREATE TABLE Users
           (
             UserName varchar(15) NOT NULL PRIMARY KEY,
             Password varchar(15) NOT NULL,
             Active Bool DEFAULT TRUE
           )

После этого создайте триггер:

delimiter $$
CREATE TRIGGER myTrigger
   BEFORE INSERT ON Users
   FOR EACH ROW
 BEGIN
   IF CHAR_LENGTH(NEW.UserName) < 4 THEN
     DELETE FROM Users WHERE Users.UserName=NEW.UserName;
   END if;
 END$$
delimiter ;
0 голосов
/ 11 августа 2010

Проблема, описанная в вопросе, звучит как идеальный кандидат для ограничения CHECK - добавьте эту строку в определение таблицы.

CONSTRAINT born_in_the_past CHECK (дата рождения <= now ()) </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...