我有桌子:作者和奖励(一对多关系)。我想制定下一条规则:
我用过
constraint foreign key (author_id)
references authors (author_id)
on delete cascade on update cascade
但无论如何我可以从奖励中删除行或所有行。如果我删除作者,我怎样才能从奖励中删除?
创建表格:
create table authors (
author_id bigint not null auto_increment,
birth_date datetime,
first_name varchar(255),
last_name varchar(255),
sex varchar(10),
primary key (author_id)
);
create table rewards (
reward_id bigint not null auto_increment,
title varchar(255),
year integer not null,
author_id bigint not null,
primary key (reward_id),
constraint foreign key (author_id) references authors (author_id)
on delete cascade on update cascade
);
然后插入值:
Insert into authors(
birth_date, first_name, last_name, sex) values
('1941-05-24', 'Bob', 'Dylan', 'male'),
('1870-10-22', 'Ivan', 'Bunin', 'male');
Insert into rewards(year, title, author_id) values
(2016, 'Nobel Prize for Literature', 1),
(1933, 'Nobel Prize for Literature', 2),
(1903, 'Pushkin Prize', 2)
;
答案 0 :(得分:0)
使用触发器足够简单,但您可能需要一个覆盖选项,可能基于另一个表。
drop trigger if exists delete_rewards;
delimiter $$
CREATE DEFINER=`root`@`localhost` TRIGGER `delete_rewards` BEFORE delete ON `rewards`
FOR EACH ROW
begin
declare msg varchar(100);
declare found int;
set found = 0;
select count(*) into found from authors a where a.author_id = old.author_id;
if found > 0 then
set msg = 'Delete Not allowed';
signal sqlstate '45000' set message_text = msg;
end if;
END $$
delimiter ;
答案 1 :(得分:0)
在制定约束时,您无法删除作者而不删除所有奖励。但您可以根据需要删除奖励。这是典型的一对多关系,其中一个是作者,而很多是奖励。这是有道理的,因为只要很多引用它,您就不想删除一个。 级联将起作用。
如果您想要防止操纵奖励记录,只要它们被分配,我就会推荐触发器和可能的历史记录表。
如果你想要一个奖励和许多作者,你必须扭转这种关系。所以作者必须参考他们的奖励。如果它是多对多,你将需要一个额外的表来处理这个问题。但是看到你的最后一个条件,我怀疑情况并非如此。