这是我遇到的一个特殊问题, 但我从来没有真正找到一个解决这个(看似)简单问题的简单方法。
如何确保给定的父母有固定数量的孩子?
1)例子。
如何确保某个课程只有50名学生注册??
create table class(
class_id number primary key,
class_name varchar2(50),
class_attributes varchar2(50)
);
create table student(
student_id number primary key,
student_name varchar2(50),
student_attributes varchar2(50)
);
create table class_student_asc(
class_id number,
student_id number,
other_attributes varchar2(50),
constraint pk_class_student_asc primary key (class_id,student_id),
constraint fk_class_id foreign key (class_id) references class(class_id),
constraint fk_student_id foreign key (student_id) references student(student_id)
);
这些是我所知道的实现。 让我知道您更喜欢哪一个,以及是否有更简单的方法来实现这一目标。
在子表(class_student_asc)上使用触发器实现它。
在插入前查询同一个表,更新触发器以获取计数。 由于这会给出变异表错误,因此将其拆分为两个不同的语句级别 触发器(before-statement和after-statement)来实现结果..
http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936
在类表中包含count变量,并在将记录插入子表之前锁定更新的父记录。
所以,像..
create table class(
class_id number primary key,
class_name varchar2(50),
class_attributes varchar2(50),
class_count INTEGER,
constraint chk_count_Students check (class_count <=5)
);
而不是为插入等公开表class_student_asc ... 编写一个程序,然后在所有应用程序中使用它。
procedure assign_new_student(
i_student_id number,
i_class_id number)
is
begin
select class_count
from class
where class_id = i_class_id
for update ; -- or for update nowait, if you want the other concurrent transaction to fail..
insert into class_student_asc(
class_id, student_id)
values (i_class_id,i_student_id);
update class
set class_count = class_count + 1
where class_id = i_class_id;
commit;
end assign_new_student;
当然,有一些用户有两个电子邮件地址的情况。 在这种情况下,电子邮件地址本身没有任何属性 这个表可以像
一样简单create table user_table
(
user_id number,
user_name varchar2(50),
user_email_primary varchar2(50),
user_email_secondary varchar2(50)
);
但是,我们无法对上述问题扩展相同的方法.....因为列数和约束检查会减慢插入和更新的速度。此外,这意味着我们每次更改规则时都需要添加新列。
请建议。
答案 0 :(得分:5)
对于Oracle,请考虑这种方法。
创建一个实体化视图,总结每个班级的学生人数。让mview在提交时刷新,并为mview添加一个约束,禁止每个班级超过50名学生。
此代码演示了如何在提交mview上使用快速刷新来强制执行学生计数限制
insert into class(class_id, class_name) values (1, 'Constraints 101');
insert into class(class_id, class_name) values (2, 'Constraints 201');
insert into student(student_id, student_name) values(1, 'Alice');
insert into student(student_id, student_name) values(2, 'Bob');
insert into student(student_id, student_name) values(3, 'Carlos');
create materialized view log on class_student_asc with primary key, rowid, sequence including new values;
create materialized view class_limit refresh fast on commit as
select class_id, count(*) count from class_student_asc group by class_id;
alter table class_limit add constraint class_limit_max check(count <= 2);
insert into class_student_asc(class_id, student_id) values(1, 1);
insert into class_student_asc(class_id, student_id) values(1, 2);
insert into class_student_asc(class_id, student_id) values(1, 3);
提交交易时违反约束,而不是在第三个学生被添加到课程时。这可能会对您的应用程序代码产生影响。 SQL Developer无法显示错误,但sql * plus确实显示错误。
答案 1 :(得分:0)
我可以想到几种方法:
<强> 1。触发器强>
在表上检查INSERT并为您进行验证。
<强> 2。一对一的关系
假设你想要一个父母只有两个孩子。创建两个一对一的关系。
答案 2 :(得分:0)
另一个问题有类似的要求,您可以使用CHECK约束和“count”列上的UNIQUE约束的组合来约束: