2013-06-04 54 views
0

喜的IM试图创建该表的触发器:触发问题与语法

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; 

这是保存一些电视系列DB表...所以触发器必须检查IM试图插入一个在先例之前已经播出的新剧集......但是我遇到了一些问题吗? 我试过这个:

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; 

end;

回答

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演示。 取消注释最后一个INSERT语句

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

  1. 您可以使用SIGNAL但只有当你的MySQL 5.5及更高版本
  2. 使用一个的hackish方式(例如,TRIGGERs that cause INSERTs to fail? Possible?Throw an error in a MySQL trigger
+0

啊确定它那真棒,但是是我第一次看到 Skyzzo

+0

@Skyzzo ** ['NEW'](http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html)**是一个别名,它允许您引用正在插入(或更新)的行。 'NEW.aired'和'NULL'是** ['IF()'](http://dev.mysql.com/doc/refman/5.5/en/control-flow-functions)的第二和第三个参数。 html#function_if)**函数。它允许检查条件,如果它是真的返回正在插入的值(NEW.aired),并且它返回NULL,则违反约束条件。 – peterm

0

如果我是你,我不会在没有必要时使用触发器。

您可以使用

请在我挂了additiona相应手册页看看l信息。

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

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小号