MySQL触发器在某些条件下阻止INSERT

Igo*_*gor 35 mysql sql

我想制作一个触发器,如果​​未来的生日(其中一列),将阻止插入.我有这个:

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;
Run Code Online (Sandbox Code Playgroud)

如何取消if语句中的插入?

Eri*_*ski 48

示例1,MySQL,您可以在触发器中取消该插入 signal sqlstate

  1. 使用varchar列创建表:

    mysql> create table yar (val VARCHAR(25) not null);
    Query OK, 0 rows affected (0.02 sec)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建'before insert'触发器以检查条件并禁用.

    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)
    
    Run Code Online (Sandbox Code Playgroud)
  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)
    
    Run Code Online (Sandbox Code Playgroud)

你插入一个空白字符串,触发器看到它是空白的,并提出信号,以防止插入.

示例2,MySQL,通过使数据违反非空约束来取消触发器中的插入.

  1. 使用varchar列创建表:

    mysql> create table yar (val VARCHAR(25) not null);
    Query OK, 0 rows affected (0.02 sec)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建'before insert'触发器以检查条件并禁用.

    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)
    
    Run Code Online (Sandbox Code Playgroud)
  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)
    
    Run Code Online (Sandbox Code Playgroud)

您插入了一个空白字符串,触发器看到它是空白的并将值更改为null,因此阻止插入.


小智 12

我不知道是否要迟到但你现在可以这样做:

SIGNAL SQLSTATE '45000' 
SET MESSAGE_TEXT = "your error text";
Run Code Online (Sandbox Code Playgroud)

PS不要忘记在触发器之前和之后修改分隔符...


mug*_*son 8

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 ;
Run Code Online (Sandbox Code Playgroud)


Ric*_*ams 7

基于此,我不确定是否可以这样做.

MySQL的当前触发器实现不支持自动抛出异常并中止产生触发器的语句.

我发现的解决方法是编写一个BEFORE触发器,将表中的一个非NULL列设置为NULL,从而违反其NOT NULL约束.这会导致产生触发器的语句被中止.

  • 读者请注意这句话是[不再正确.](http://stackoverflow.com/a/22489342/1446005) (19认同)