0

大家好,我试图为此表创建触发器:

create table Episode(
  title varchar(25) not null,
number int not null,
  length time not null,
  aired date not null,
  serie_name varchar(25),
PRIMARY KEY(title,number),
  FOREIGN KEY (serie_name)REFERENCES Serie(name)
  ) ENGINE=InnoDB;

这是一个保存一些电视剧的数据库表……所以触发器必须检查我是否试图插入一个在前一集之前播出的新剧集……但我有一些问题有什么解决方案吗?我试过这个:

create trigger ControlDataEp
 before insert on Episode
 for each row
begin
if new.aired<(select aired from Episode where title=new.title and number=new.number-1)
    then raise.application_error(-21,'error');
end if;

结尾;

4

2 回答 2

0

如果我是你,我不会在不需要的时候使用触发器。

您可以使用

请查看我链接的相应手册页以获取更多信息。

解释一下,为什么您的解决方案不起作用:

if new.aired<(select aired 

您的子查询可能会返回多行。改为使用SELECT MAX(aired) ...

... and number=new.number-1)

依靠数据库外部的代码来确保数据库中的数据正常是一个坏主意。

then raise.application_error(-21,'error');

raise.application_error()不是 MySQL 内置函数。您不能像这样从 MySQL 中的代码调用函数。如果您真的想在 MySQL 中引发错误,请使用SIGNAL s

于 2013-06-05T03:12:33.003 回答
0

如果您不太关心返回有意义的错误消息,则可以将触发器简化为一条语句

CREATE TRIGGER ControlDataEp
BEFORE INSERT ON Episode
FOR EACH ROW
SET NEW.aired = 
(
  SELECT IF(IFNULL(MAX(aired), 0) < NEW.aired, NEW.aired, NULL)
    FROM Episode 
   WHERE title = NEW.title 
     AND number = NEW.number - 1
);

它的作用违反了对列的NOT NULL约束。aired

这是SQLFiddle演示。取消注释最后一个插入语句

现在,如果您确实需要返回自定义错误消息:

  1. 您可以使用SIGNAL,但前提是您在 MySql 5.5 及更高版本上
  2. 使用一种骇人听闻的方式(例如阅读导致 INSERT 失败的触发器?可能吗?在 MySQL 触发器中引发错误
于 2013-06-05T03:35:15.970 回答