表tbJbxx:nsid,xm,school 主键nsid
tbKmOne:nsid,kscs,ksdc 主键nsid+kscs
tbKmTwo:nsid,kscs,ksdc 主键nsid+kscs
tbKmThree:nsid,ksdc 主键nsid+kscs
ksdc为考试等次,只有合格、不合格两种取值,kscs为考试次数
一个nsid在tbkmone、tbkmtwo、tbkmthree三个表中可能有多条记录,也可能没有记录,但每个表中只有一条ksdc为合格的记录
tbkmone、tbkmtwo、tbkmthree分别与主表tbjbxx通过nsid外键相连;
业务逻辑要求是:一个nsid只有在bkmone合格后才能考tbkmtwo、tbkmtwo考试合格后才能考thkmthree,每个nsid对每门科目均可以进行多次考试直至合格
设计出现的问题:
通过delphi实现客户端业务处理,用户可能在thkmthree中有合格记录后,在tbkmtwo中删除合格记录,至使数据库记载的信息不符合业务逻辑要求。
提问:当然可以通过delphi编写客户代码限制上述不合理要求。现在想从源头数据库的表设计上入手,禁止这种删除记录的方法。也就是 tbkmone、tbkmtwo、tbkmthree三个表怎样建立约束关系?
tbKmOne:nsid,kscs,ksdc 主键nsid+kscs
tbKmTwo:nsid,kscs,ksdc 主键nsid+kscs
tbKmThree:nsid,ksdc 主键nsid+kscs
ksdc为考试等次,只有合格、不合格两种取值,kscs为考试次数
一个nsid在tbkmone、tbkmtwo、tbkmthree三个表中可能有多条记录,也可能没有记录,但每个表中只有一条ksdc为合格的记录
tbkmone、tbkmtwo、tbkmthree分别与主表tbjbxx通过nsid外键相连;
业务逻辑要求是:一个nsid只有在bkmone合格后才能考tbkmtwo、tbkmtwo考试合格后才能考thkmthree,每个nsid对每门科目均可以进行多次考试直至合格
设计出现的问题:
通过delphi实现客户端业务处理,用户可能在thkmthree中有合格记录后,在tbkmtwo中删除合格记录,至使数据库记载的信息不符合业务逻辑要求。
提问:当然可以通过delphi编写客户代码限制上述不合理要求。现在想从源头数据库的表设计上入手,禁止这种删除记录的方法。也就是 tbkmone、tbkmtwo、tbkmthree三个表怎样建立约束关系?
现在客户把tbkmtwo中合格的信息删除了,该表中只剩下不合格的记录,而thkmthree中仍然有一条合格记录。
按照业务逻辑要求tbkmtwo中没有合格记录,thkmthree是不应该有记录的,当然更不能有合格记录了。
唉,数据库功底不扎实啊,临时抱佛脚,结果搞出这么多问题。
另外昨天您教我的SQL语句还没完全看懂
select M.NSID, m.xm, m.xb, M.SCHOOL,
case when a.g1>0 then '合格'
when a.g2>0 then '不合格'
else null
end ksdcA, --a科目成绩
case when b.g1>0 then '合格'
when b.g2>0 then '不合格'
else null
end ksdcb, --b科目成绩
case when c.g1>0 then '合格'
when c.g2>0 then '不合格'
else null
end ksdcc --c科目成绩
from m left join
(select nsid,
count(case when ksdc = 'Y' then 1 else null end) g1, --合格次数
count(case when ksdc = 'N' then 1 else null end) g2 --不合格次数
from a
group by nsid
) a on m.nsid = a.nsid
left join
(select nsid,
count(case when ksdc = 'Y' then 1 else null end) g1, --合格次数
count(case when ksdc = 'N' then 1 else null end) g2 --不合格次数
from b
group by nsid
) b on m.nsid = b.nsid
left join
(select nsid,
count(case when ksdc = 'Y' then 1 else null end) g1, --合格次数
count(case when ksdc = 'N' then 1 else null end) g2 --不合格次数
from c
group by nsid
) c on m.nsid = c.nsid
为何可用a.g1、a.g2、a.g3?上行中为何可用c on m.nsid = c.nsid,此处的C是指什么呢?
可能同时还要建updata触发器,因为用户可能不删除合格记录,但可将合格记录更改为不合格,这样同样不合业务逻辑。
或者,你可以采用下面的做法就会好理解些。
select M.NSID, m.xm, m.xb, M.SCHOOL,
case when x.g1>0 then '合格'
when x.g2>0 then '不合格'
else null
end ksdcA, --a科目成绩
case when y.g1>0 then '合格'
when y.g2>0 then '不合格'
else null
end ksdcb, --b科目成绩
case when z.g1>0 then '合格'
when z.g2>0 then '不合格'
else null
end ksdcc --c科目成绩
from m left join
(select nsid,
count(case when ksdc = 'Y' then 1 else null end) g1, --合格次数
count(case when ksdc = 'N' then 1 else null end) g2 --不合格次数
from a
group by nsid
) x on m.nsid = x.nsid
left join
(select nsid,
count(case when ksdc = 'Y' then 1 else null end) g1, --合格次数
count(case when ksdc = 'N' then 1 else null end) g2 --不合格次数
from b
group by nsid
) y on m.nsid = y.nsid
left join
(select nsid,
count(case when ksdc = 'Y' then 1 else null end) g1, --合格次数
count(case when ksdc = 'N' then 1 else null end) g2 --不合格次数
from c
group by nsid
) z on m.nsid = z.nsid
不知兄弟客户端常使用什么工具,本人喜欢delphi