MySQL触发器未正确检查变量

时间:2019-01-14 19:17:45

标签: mysql database-trigger

我是MySQL触发器的新手,如果条目无效,我想阻止它们存储在数据库中。在这种情况下,我想检查模块年数是否大于课程的年数。

这是我的过程(此操作在插入之前执行)。

SELECT num_of_years INTO @num_years FROM courses WHERE courses.course_id = NEW.course_id;

IF NEW.course_year > @num_years THEN
UPDATE `Error: invalid_id_test` SET x=1;
END;

为什么这允许进入任何学年,我该如何解决?

1 个答案:

答案 0 :(得分:2)

编辑:现在,我对问题有了更深入的了解,修订了答案。

这是一个测试。

create table courses (
  course_id int primary key,
  num_of_years tinyint unsigned default 1
);

create table modules (
  module_id int primary key,
  course_id int,
  course_year tinyint unsigned
);

delimiter ;;
create trigger t before insert on modules for each row 
begin 
  declare num_years tinyint unsigned; 
  select num_of_years into num_years from courses where course_id = NEW.course_id; 
  if NEW.course_year > num_years then 
    signal sqlstate '45000' 
      set message_text = 'course_year is larger than the course length'; 
  end if; 
end;;
delimiter ;

这类作品:

insert into courses set course_id=1, num_of_years=3;

insert into modules values set module_id=1, course_id1, course_year=4;
ERROR 1644 (45000): course_year is larger than the course length

但是,如果course.num_of_years为NULL,这不会阻止INSERT。

insert into courses set course_id=2, num_of_years=NULL;

insert into modules set module_id=2, course_id=2, course_year=99;
Query OK, 1 row affected (0.01 sec)

原因是触发器中的变量为NULL,因此NEW.course_year > num_years 不正确,并且不会引发异常。

要解决此问题,请检查NULL。

delimiter ;;
create trigger t before insert on modules for each row 
begin 
  declare num_years tinyint unsigned; 
  select num_of_years into num_years from courses where course_id = NEW.course_id; 
  if num_years is NULL or NEW.course_year > num_years then 
    signal sqlstate '45000' 
      set message_text = 'course_year is larger than the course length'; 
  end if; 
end;;
delimiter ;

insert into modules set module_id=2, course_id=2, course_year=99;
ERROR 1644 (45000): course_year is larger than the course length

如果您尝试为找不到的course_id插入模块,这也会引发错误。同样,这将使num_years为NULL,因此我们需要在触发器中进行检查。

insert into modules set module_id=2, course_id=5, course_year=99;
ERROR 1644 (45000): course_year is larger than the course length