目录
前言
学生选课数据库存储了大量的学生、老师、课程信息以及学生的选课记录。我们在使用学校的教务系统选课时可以注意到,当我们选了一门课之后便不能再点击这一门课或者选择这门课程其他老师的课,必须将这一门课退掉之后才能重新选择其他老师的课或再次选择之前老师的课。
在选课系统对应的数据库的选课表中,学生每选择一次课就会多一条记录,每退一次课就会减少一条记录。但对于学习数据库初期的同学来说有一件比较尴尬的事就是数据库没有防止重复选课的功能,当学生重复选课时就会一直有同样的记录插入到表中,这就会导致在查询时产生的不便。
我在创建选课数据库时也碰到了这样的问题,一开始没解决好,但后面还是通过SQL的方法解决这个尴尬的问题。
为了方便,文章的表不会创建外键,仅以简单的形式表达。
演示表:
问题演示
向选课表中插入重复记录无任何提示及报错,导致数据库功能不完整。
可以看到选课表中有多条相同的记录,而我们选课数据库是不能这样的。
问题解决
这个问题我们有两种方式解决,分别是使用组合主键和 INSTEAD OF 触发器。
使用组合主键
主键的性质是数据不能为空且唯一,使用组合主键就是利用了主键字段数据唯一的特性。
将学号字段与课程号字段创建组合主键,它起到的作用就是保证了学号与课程号这对组合在选课表中的唯一性,当其中一个存在相同时不会阻止插入新纪录,一旦两者同时存在相同的数据时便不能再插入新纪录。
代码演示:
效果演示:
插入与已存在的记录形同的新纪录时报错:
有一个不同时可以插入:
使用 INSTEAD OF 触发器
触发器是当我们对数据库做出操作时才会执行的动作,我们使用 INSTEAD OF 触发器在INSERT语句之前对数据进行判断。
在触发器中,我们使用表变量存储选课表中一个学生的全部选课信息,再判断该学生的选课信息中是否包含将要选择的课程号。如果包含,则将数据回滚并提示“不能重复选课”,否则提示“选课成功”并将inserted表中的数据复制到选课表中,完成选课。
注意:存储一个学生的全部选课信息也可以使用临时表。
代码演示:
效果演示:
1.当执行以下代码时:
结果:选课成功是第一行代码成功选课,提示不能重复选课是第二行代码触发的。
2.当执行以下代码时:
结果:提示两次“选课成功”,调用两次SELECT语句。
总结
防止重复选课对于选课系统来说及其重要,对于数据库的数据存储一样重要。在我碰到这个问题时也懵了好一会,就在想如果能够重复选课的话,那我是不是可以选择几百次体育课呀,哈哈。后来突然想到了组合主键这个概念,当初只是匆匆一瞥都没有好好看过它,但是他给我的帮助确实不小。其实这个问题是我在设置触发器的时候碰到的,一开始也因为临时表的错误使用让我苦恼了好一会,但最后还是可以使用触发器把这个问题解决了。可以说主键是我们在开发数据库的很重要的一个知识,同时,触发器也能让我们更好的解决问题。
这个问题给我的感受就是我们在平时的学习当中不要因为某些知识不起眼、不常用而忽略了他们,在关键时刻他们也能够发挥大作用!