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?
Ответы
Ответ 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())