我有三张桌子:
学生(snum(主键),sname)
注册(snum,tname)
训练(tname(主键),tdate,thour,troom)
我必须在注册表中设置约束,以便学生不能注册同时给出的课程(tname)。
我尝试过这样的事情,但我认为它只是给出了独特的课程:
select tname from Training T1 where tdate not in (select tdate from Training T2 where T1.tdate=T2.tdate)
答案 0 :(得分:1)
您可能必须在“插入前”和“更新前”编写触发器。 在触发器中获取您要比较的数据,然后在数据与您的条件不匹配时拒绝插入或更新
答案 1 :(得分:1)
如果您同意拥有一些冗余,则可以创建此类约束。
这就是你要做的:
在(tname, tdate, thour)
中的Training
创建一个唯一约束:
ALTER TABLE Training ADD CONSTRAINT
UQ_Training_NameDateHour UNIQUE (tname, tdate, thour);
再向Enrolled
添加两列:
ALTER TABLE Enrolled ADD tdate date NOT NULL;
ALTER TABLE Enrolled ADD thour int NOT NULL;
我猜这里的类型。他们需要匹配Training
。
让新列成为对Training
的引用的一部分:
ALTER TABLE Enrolled ADD CONSTRAINT
FK_Enrolled_Training FOREIGN KEY (tname, tdate, thour)
REFERENCES Training (tname, tdate, thour);
如果您已经有一个仅指向tname
的引用,则可以将其删除。
最后,在Enrolled
中创建一个唯一约束,以确保每个tdate
thour
和snum
是唯一的:
ALTER TABLE Enrolled ADD CONSTRAINT
UQ_Enrolled_NumDateHour UNIQUE (snum, tdate, thour);
通过这种方式,您将对Enrolled
表格进行正式约束,以确保学生无法同时开始培训。
当然,当您将行插入Enrolled
时,引用必须包含所有三个组件。如果您觉得价格太高,那么您可能不得不求助于使用触发器as suggested by Norbert van Nobelen。