数据库触发器控制

①选修成绩表SCTS中,学生选修成绩由平时成绩(regular_grade)和考试成绩(exam_grade)构成课程总评成绩(total_mark),公式为:total_mark= regular_grade*30%+ exam_grade*70%

  设计DML触发器,使得当用户修改某位学生选修某门课程的平时成绩或者考试成绩时,自动实现对该学生该门课程总评成绩的更新。


Create trigger Tri_UPDATE_SCTS

on SCTS

after UPDATE

AS

BEGIN

IF UPDATE(regular_grade)or UPDATE(exam_grade)

BEGIN

DECLARE @rgrade float;

DECLARE @egrade float;

select @rgrade=regular_grade,@egrade= exam_grade from inserted

update SCTS

set total_mark=0.3*@rgrade+0.7*@egrade

from inserted

where SCTS.studentid =inserted.studentid

and SCTS.courseid=inserted.courseid

and SCTS.teacherid =inserted.teacherid

END

END

  --测试触发器


update  Scts

set regular_grade='100',exam_grade='100'

where studentid='200520805403'and courseid='20224B0' and teacherid='080102'

select *from scts

where studentid='200520805403'and courseid='20224B0' and teacherid='080102'

  --2、②设计DML触发器,使得当某学生在一个学期中所选修的课程总学分超过20学分时,自动提示“你选修的总学分已达到最大值,不允许继续选课!”的信息;


Create trigger Tri_IN_LIMIT_SCTS

on SCTS

after insert --注意这里AFTER是插入之后的

AS

BEGIN

BEGIN

DECLARE @allcredit float;

DECLARE @sid varchar(12);

select @sid =inserted.studentid from inserted

select  @allcredit=sum(credit)

from courses

where courseid in(

select courseid

from scts

where studentid=@sid

)

if (@allcredit>20)

begin

Rollback Transaction

print @allcredit

print'你选修的总学分已达到最大值,不允许继续选课!'

end

else

print'选课成功'

END

END

 --测试触发器


select  sum(credit) '总分'

from courses

where courseid in(

select courseid

from scts

where studentid='200520701201'

)

insert into Scts(courseid,studentid,teacherid)

values ('50103Q0','200520701201','080102');

select *from courses where courseid='10042B0'

  --3.设计DML触发器限定:对于“专业”(COURSES.character,包括专业课、专业基础、专业选修等)课程,只有该课程开课学院的学生才能选修,否则提示“不允许跨院选课!”的提示信息。


Create trigger Tri_INSERT_SCTS

on SCTS

after insert

AS

BEGIN

DECLARE @stype varchar(10);

DECLARE @collegeid varchar(5);

if exists(select * from courses AS C

where C.courseid in(select courseid  from inserted ) and C.Character like '专业%')

BEGIN

select @collegeid=college from courses AS C

where C.courseid in(select courseid  from inserted )

if exists (select college from students AS S

where S.studentid in(select studentid  from inserted )and S.college=@collegeid)

PRINT '选专业课成功'

else

BEGIN

Rollback Transaction

PRINT '不允许跨院选课!'

END

END

ELSE

PRINT '选修公共选修课成功'

END

  --选修本学院专业课

  insert into Scts(courseid,studentid,teacherid)

  values ('20224B0','200520805403','080102');

  --选修非本院专业课 终止

  insert into Scts(courseid,studentid,teacherid)

  values ('10019B5','200520805403','080102');

  --选修公共选修课


insert into Scts(courseid,studentid,teacherid)

values ('50095Q0','200520805403','080102');

select *from students where college='08'

select *from colleges where collegeid='08'

select *from courses where courseid in (select courseid from courses where character not like '专业%')and college

='08'

select *from scts where studentid='200520805403'

delete from scts  where  courseid='20224B0' and  studentid='200520805403';

  --4、设计DML触发器以实现对敏感数据的自动审计:当用户在SCTS表中插入新记录或者更新SCTS表中的regular_grade和exam_grade属性列时,自动在成绩变化表GRADE_LOG(student, course, teacher, regular_grade, exam_grade, username, userdate)中增加一条相应记录,以记录当前用户对学生成绩的操作。(system_user)


Create table GRADE_LOG(

id int  identity(1,1) primary key,

student varchar(20) not null ,

course  varchar(50) not null,

teacher varchar(20) not null,

regular_grade float ,

exam_grade float,

username  varchar(20) not null,

userdate datetime not null,

operator varchar(10) not null

)

--select system_user  getdate()

Create trigger  Tri_IN_U_SCTS

on SCTS

after INSERT,UPDATE

AS

BEGIN

IF UPDATE(regular_grade)OR UPDATE(exam_grade)or (exists (select 1 from inserted) and not exists (select 1

from deleted))

BEGIN

DECLARE @student varchar(20);

DECLARE @course varchar(50);

DECLARE @teacher varchar(20);

DECLARE @rgrade float;

DECLARE @egrade float;

DECLARE @username  varchar(20);

DECLARE @date datetime;

DECLARE @type varchar(10);

select @type='update';

if exists (select 1 from inserted) and not exists (select 1 from deleted)

select @type='insert';

select @student=sname from students where studentid in(select studentid  from inserted )

select @course =cname from courses where courseid in (select courseid from inserted)

select @teacher =tname from teachers where teacherid in (select teacherid from inserted)

select @rgrade=regular_grade,@egrade=exam_grade from inserted

select @username=system_user,@date=getdate();

insert into GRADE_LOG

values(@student,@course,@teacher,@rgrade,@egrade,@username,@date,@type)

END

END

select * from  GRADE_LOG;

  --更新成绩

  update  Scts

  set regular_grade='100',exam_grade='20'

  where studentid='200520805403'and courseid='20224B0' and teacherid='080102'

  --只更新总成绩,不激活触发器

  update  Scts

  set total_mark='100'

  where studentid='200520805403'and courseid='20224B0' and teacherid='080102'

  --5、DDL触发器,禁止用户在Teaching数据库中的修改表和删除表操作。


CREATE TRIGGER TRI_Teaching_DDL

ON database

for alter_table,drop_table

AS

BEGIN

print '不允许修改或删除数据表!'

Rollback Transaction

END

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-09-28 21:06:57

数据库触发器控制的相关文章

sqlserver 存储过程-关于一个数据库触发器的问题

问题描述 关于一个数据库触发器的问题 请教一个数据库相关的问题 各位大神好,小弟现正使用sqlserver数据库,现有这么一个需求, 需要监视有关 表A 的插入,修改,删除 操作,并需要将新的整条数据形成类似 <tbrecord id="某一行的ID" columnAname="该行的列名为columnAname的值" columnBname="该行的列名为columnAname的 值">tbName(表的名称) 一个xml字符串保存

ASP数据库事务控制的实现

在编程中,经常需要使用事务.所谓事务,就是一系列必须都成功的操作,只要有一步操作失败,所有其他的步骤也必须撤销.比如用ASP开发一个网络硬盘系统,其用户注册部分要做的事有: 将用户信息记入数据库 为用户开个文件夹用于存储 初始化用户操作日志 这三步必须使用事务,否则万一磁盘操作失败,而没有撤销数据库操作,就会造成只能登陆而不能操作的"死用户"现象. 由于数据库系统特殊的发展历史,小至Access,大到DB2,无不带有事务支持.因此上述步骤可以如下表示: On Error Resume

PPT幻灯片中怎么使用触发器控制声音

  PPT幻灯片中怎么使用触发器控制声音         1.在幻灯片中选择音频图标,在功能区中打开"动画"选项卡,单击"高级动画"组中的"动画窗格"按钮打开"动画窗格"窗格,如图1所示. 图1 打开"动画窗格"窗格 2.在"动画窗格"窗格中单击声音选项右侧的下三角按钮,在打开的下拉列表中选择"效果选项"选项,如图2所示.此时将打开"播放音频"对话

spring-hibernate 与数据库触发器的问题

问题描述 hibernate 与数据库触发器的问题 今天碰到个jpa(hibernate) 与数据库触发器共存的问题. 有两张表A 和B,在表A上写了个触发器,当对A表某列进行update操作的时候,触发更新B的某条记录,但是hibernate 报如下错误: "Batch update returned unexpected row count from update; actual row count: 2; expected: 1". hibernate执行update操作时,返回

link中如何调用数据库触发器?需要自己写语句么?

问题描述 link中如何调用数据库触发器?需要自己写语句么? link中如何调用数据库触发器?需要自己写语句么? 解决方案 http://bbs.csdn.net/topics/310207347

请问数据库触发器有什么用

问题描述 请问数据库触发器有什么用 请问,数据库 触发器有什么用,求各位大神前来相助,请说详细点哦.谢谢了 解决方案 在插入.修改等操作发生的时候,允许dba执行一段自定义的代码. 比如说,插入数据后添加一条日志.没有触发器,这样的逻辑,每次查询都要写一遍,就很麻烦,也不好维护. 有了触发器就简单了,只要写在一处就可以了. 解决方案二: 网上没有搜到你想要的答案吗?http://blog.csdn.net/chinayuan/article/details/6292335/ 解决方案三: 在插入

为数据库添加控制文件

      此文承接上一篇文章,由于对单个控制文件恢复后,数据库里只有一个控制文件,所以要为数据库添加控制文件. 1)在nomount状态修改spfile文件.由于数据库里只有一个控制文件control03.ctl 先将control03.ctl拷贝后重命名为control01.ctl ,control02.ctl , SQL> conn system/yang as sysdbaConnected to an idle instance. SQL> startup nomountORACLE

ORACLE 触发器控制用户登录之权限限制

    出于数据安全性,公司要求DBA实现控制拒绝特定的用户登录,由于公司不同的工作楼层分属于不同的vlan,因此单从linux主机层次依赖ACL访问列表控制登录数据库服务器,已经不能实现. 因此,只能考虑从数据库内部加以限制登录数据库,也就是借助oracle Trigger实现登录验证,实现方法就是捕获到拒绝登录的用户就抛应用异常强制用户退出登录,也就是使用Raise_Application_Error 实现,但是需要注意的是,被限制的用户不能有DBA权限,也不能有imp_full_datab

在ASP程序中实现数据库事务控制

程序|控制|数据|数据库     在编程中,经常需要使用事务.所谓事务,就是一系列必须都成功的操作,只要有一步操作失败,所有其他的步骤也必须撤销.比如用ASP开发一个网络硬盘系统,其用户注册部分要做的事有: 将用户信息记入数据库 为用户开个文件夹用于存储 初始化用户操作日志 这三步必须使用事务,否则万一磁盘操作失败,而没有撤销数据库操作,就会造成只能登陆而不能操作的"死用户"现象. 由于数据库系统特殊的发展历史,小至Access,大到DB2,无不带有事务支持.因此上述步骤可以如下表示: