MySQL 触发器未正确检查变量
MySQL trigger not checking variable correctly
我是 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;
为什么这允许进入任何课程年,我该如何解决?
编辑:修改后的答案,现在我对问题有了更好的理解。
这是一个测试。
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
但如果 courses.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
我是 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;
为什么这允许进入任何课程年,我该如何解决?
编辑:修改后的答案,现在我对问题有了更好的理解。
这是一个测试。
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
但如果 courses.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