Редактировать: Исправлен ответ, теперь я лучше понимаю проблему.
Вот тест.
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
Но это не помешает INSERT, если courses.num_of_years имеет значение NULL.
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