Подтвердить что ты не робот

MySQL Trigger для предотвращения INSERT при определенных условиях

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

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?

4b9b3361

Ответ 1

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

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

Обходной путь, который я нашел, - написать триггер BEFORE, чтобы установить один из not-NULL в таблице до NULL, нарушив его NOT NULL ограничение. Это приводит к утверждению который породил триггер, чтобы прервана.

Ответ 2

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

  • Создайте таблицу с столбцом varchar:

    mysql> create table yar (val VARCHAR(25) not null);
    Query OK, 0 rows affected (0.02 sec)
    
  • Создайте триггер "перед вставкой", чтобы проверить состояние и запретить.

    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)
    
  • Попробуйте вставить, где выполняется условие:

    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, Отмените вставку в триггере, заставив данные нарушить не нулевое ограничение.

  • Создайте таблицу с столбцом varchar:

    mysql> create table yar (val VARCHAR(25) not null);
    Query OK, 0 rows affected (0.02 sec)
    
  • Создайте триггер "перед вставкой", чтобы проверить состояние и запретить.

    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)
    
  • Попробуйте вставить, где выполняется условие:

    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)
    

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

Ответ 3

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

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

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

Ответ 4

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 ;

Ответ 5

У меня была та же проблема. Я создал таблицу, но не было возможности назначить минимальную длину строки в 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 ;

Ответ 6

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

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