所以我应该使用一个叫做课堂的桌子,包括学生,性别(M / F),座位#和座位(A / B)。我正在尝试创建一个触发器,阻止用户将学生插入已经存在的座位#和seatsection。此外,每个座位号的部分必须由同性别的学生占用。如果insert语句违反了这些规则,则应生成相应的错误消息。
这是我提出的草稿:
create or replace trigger trigstudent
before insert on classroom for each row
BEGIN
if :new.seat# = :old.seat# then
if :new.seatsection = :old.seatsection then
-- raise an error message saying students can't take someone else's seat
else
if :new.gender = :old.gender then
-- raise error message saying that only students of the same gender can sit together
end if;
end if;
end if;
我显然后来意识到你不能使用" new"和#34;老"对于插入语句。所以我一直坚持这一点,不知道该怎么做。任何帮助将不胜感激。
答案 0 :(得分:0)
使用触发器实现该逻辑实际上非常困难 - 它实际上是一个建模问题,即对表进行建模以允许标准数据库约束来控制数据验证。
特别是,没有数据库限制,面临的挑战是确保人X不添加/更新行,而Y人正在做同样的事情,并使用未提交的更改创建违规(您的会话无法看到。)
所以这里有一个如何实现它的例子,但这是一种强力方法,即在允许插入后我们触发一个触发器
但我强调,这通常不是现实世界中的可持续解决方案'
create or replace trigger trigstudent
after insert or update on classroom
DECLARE
x int;
BEGIN
lock table classroom in exclusive mode nowait;
select count(*) into x from dual
where exists (
select count(*) from classroom group by seat# having count(*) > 1
);
if x > 0 then
raise_application_error(-20000,'There are some seat duplicates');
end if;
select count(*) into x from dual
where exists (
select count(distinct gender) from classroom group by section# having count(distinct gender) > 1
);
if x > 0 then
raise_application_error(-20000,'There are some clashing genders per section');
end if;
end;
/