SQL Server 2008 R2数据库存储过程和触发器

实验名称:存储过程和触发器

实验目的:

1.掌握存储过程的概念、功能等

2.掌握用户自定义存储过程的创建、修改、删除和执行

3.掌握触发器的概念和功能

4.掌握触发器的创建、修改、删除及其使用方法

实验意义:

1.存储过程的创建可以对数据操作过程加密,使用户只能输入相应参数完成操作得到输出结果,并不能查看到源代码,对于数据库的安全性具有重要意义。

2.存储过程效率较高,通过自定义的存储过程,可以反复进行调用,避免多次重复输入相似的代码从而降低效率。

3.触发器的存在可以使表与表之间实现一定的约束或者实现级联更新的操作,通过触发器的创立,用户在执行某些操作时可能会不满足条件而终止,也可以产生相应的该表或者其他表的数据更新的效果。

实验内容:

  • 创建并执行存储过程
  • 修改存储过程
  • 删除存储过程
  • 创建和执行触发器
  • 修改触发器
  • 删除触发器
  • 习题
  • 总结与心得体会

实验主要步骤:

  • 创建并执行存储过程

1.交互式创建存储过程

在打开显示的界面中,修改参数,输入SQL语句进行创建存储过程如下,通过学生学号来查询学生的姓名、年龄、系名,并设置默认学号为S2。在存储过程中声明变量,定义参数,执行查询SQL赋值语句,并且将查询结果传出存储过程:

       执行SQL语句,调用创建的存储过程,先调用参数为默认学号为S2的学生查询存储过程,再调用学号参数为S4的学生的查询过程,并且打印出学号,年龄与系别。

2.T-SQL语句创建存储过程

       通过学生姓名和课程名查询该生该课程的成绩

新建查询,创建存储过程,首先声明变量,并且声明变量的类型,采用表的连接方式,并且执行条件语句WHERE选中该学生与该课程,在SELECT中即可完成参数的传出。

       执行T-SQL语句,同样先声明变量与存储类型,再采用SELECT进行赋值操作,也可以采用SET对学生名与课程名进行赋值,最后再调用存储过程,将参数输入,最终在调用存储过程后将学生姓名与选课成绩打印出来。

  • 修改存储过程

1.交互式修改存储过程Pro_Qsinf

在对象资源管理器中,找到对应表下的存储过程,右击该存储过程,点击“修改”,将变量SNO_IN的长度修改为2,输出变量SAGE_OUT的类型改为TINYINT。

修改之后的结果如下所示,并单击执行,将其再次保存。

2.T-SQL语句式修改存储过程Pro_Qsinf

       执行方法是采用Alter语句,将存储过程整体结构重新编写修改,修改查询结果为查询姓名、性别与系名,并且将学号的默认值修改S1

最后在对象资源管理器中将该存储过程刷新后可以看到,该存储过程的列参数的参数类型已经发生对应的变化。

  • 删除存储过程

1.交互式删除存储过程Pro_Qsinf

在存储过程中,右击该存储过程,单击删除操作,点击确定即可完成对存储过程的删除操作。

2.T-SQL语句对存储过程进行删除

  • 创建和执行触发器

1.交互式为数据库表S创建级联更新的触发器TRIGGER_S

       该触发器作用:修改表S中学号时,SC表中该学生选课记录的学号相应发生变化,与外键相似的效果。

       在对象资源管理器中对于表C新建触发器如下:

       采用与之前新建存储过程相似的方法,将交互式中自带的语句进行修改如下,先提前定义运行条件是当表的SNO发生更新时才执行,再声明变量,进行查询语句创建操作,并且设置对应学号发生变化后,SC表中对应的学号数据也要发生变化,采用SET语句对SC表相应学号进行赋值。

       数据校验,将学号为S1学生修改学号为S5:

       执行之后,查看学生表的数据,学生“赵就”的学号由S1变成了S5

       再查看SC表中的数据,发现原本为S1学生的选课数据变成了S5的选课数据,说明触发器的创建成功。

2.交互式为数据库表SC创建限制更新触发器TRIGGER_SC

修改SC表中一记录的学号,则要求检查表S中是否存在学号相同的记录,若存在则不许修改。

以下为代码创建过程:

对SC表创建触发器,由于更新过程涉及到表DELETED,因此将删除的SNO保存为SNO_OLD,并对S表中的SNO与更新SC表前的SNO进行对比,若存在1或多条数据,由COUNT函数记录,并且当COUNT函数结果不等于0时,触发器停止运行,过程终止(ROLLBACK TRANSACTION)。

对SC表更新学号,观察S表中学号变化情况,可以看出触发器可以正常运转,并且将批处理中止。

3.用SQL语句为数据库表SC创建成绩约束触发器

       对更新后插入表内成绩进行判断,满足范围才能执行改变,范围不满足即会中止。

在SC表中插入不合格成绩数据进行测试

插入成绩合格数据再进行测试

修改更新表中数据,不合格数据如下:

修改更新表中数据,合格数据如下:

综合以上四种测试情况,可以验证出该触发器的创建的正确性。

4.用SQL语句为数据库表C创建个级联删除触发器TRIGGER_DC

       创建触发器,并且设定触发器条件为DELETE,接下来设置具体触发条件,目标为从C表的改变到SC表中课程的删除。

测试数据,对C表删除课程C1如下:

       可以查看SC表中课程C1已经不存在:

  • 修改触发器

1.交互式修改数据库表S的触发器TRIGGER_S

       与修改存储过程方法极其类似,在对象资源管理器中右击触发器,单击修改。

       修改为删除表S中信息,自动删除数据库表中与该学生相关的记录。

2.用SQL语句修改数据库表C的触发器TRIGGER_DC

       在表C中删除某课程信息,同时删除数据库表SC与TC的相关课程记录。在触发器中,增加DELETE语句,作用于SC与TC表,并且设置删除条件

  • 删除触发器

1.交互式删除触发器

       操作步骤如下图所示:

2.T-SQL语句删除触发器

习题训练

存储过程习题

1.利用学生姓名查询该生选修的课程名、成绩,以及任课教师名

       首先对存储过程进行创建,声明变量,定义参数,在查询语句中,采用SELECT输出课程名、成绩,以及任课教师名,采用多表连接的方式,并且进行设定筛选条件,打印出结果。

       调用该过程程序语句如下,经过测试仅能输出一行程序运行结果,并不满足我们真实的需求,因此在未增加游标的情况下,该存储过程执行结果是并不完整的。

3.利用学生姓名和课程名检索该生该课程的成绩

       仍然采用多表连接的方式,输出结果为年龄,查询过程比较简单,创建存储过程如下:

调用存储过程的结果如下,选用一组测试数据,并将结果打印在了显示页面上如下:

7.利用课程名查询选修该课程的学生姓名、系别、成绩,并给出某门课程的查询信息。

       在创建存储过程中,采用多表连接的方式,并确定输出列,同时打印出结果。

       调用存储过程如下,选择课程为“定位原理”,可以看出基于美存在游标的情况,输出结果仍然只是单行数据,是基于SELECT的赋值方式,仅赋值最后一次赋值的结果。

8.利用教师姓名和课程名检索该教师该认可的课程名、课时数、选课人数、平均成绩、最高成绩。

       创建存储过程如下,查询语句中,记录输出的课程名、课时数、并且记录数目、平均成绩值、最高成绩值,同时采用多表连接的方法,判断筛选条件为教师姓名与课程名,并且按照教师姓名、课程名以及课时数进行分组执行查询操作。

       调用存储过程如下,并且给出测试用例,输出结果打印至显示页面上:

触发器习题

1.为数据库表SC创建触发器:当插入或修改一个记录时,确保此纪录成绩在0-100分之间。

采用判断语句,对插入或更新表中成绩数据时,进行判断成绩的范围,满足时打印插入或修改成功,不满足时触发器自动中止该过程。

接下来是四种情况验证触发器的创建效果:

可以看出创建成功,可以符合逻辑正常运转。

3.为数据库表C、TC和SC创建参照完整性:级联删除和级联修改触发器

       主要过程实现为对C表创建触发器,触发器实现条件为C表的更新与删除,并且是对于SC与TC表相对于课程发生变化,触发器创建如下:

测试更新表CNO数据如下:

       可以看出SC与TC均发生相应的变化,课程C3已经全部转化为了C8如下:

 

       再次测试删除操作如下:

       可以看出SC与TC均发生相应的变化,课程C7已经全部被删除如下:

 

       综上所述,可以看出修改和删除操作均顺利执行!

4.为数据库表T创建触发器:当职称从“讲师”晋升为“副教授”时,岗位津贴自动增加500元,从“副教授”晋升为“教授”时,津贴自动增加900元。

       创建存储过程,该过程是单表内部的级联更新,先在初始表中保存工资值,再删除表中保存删除的职称,在插入表中保存插入的职称,接下来对职称进行判断,满足“讲师”到“副教授”,则设置其工资在原始工资上增加500元,若满足“副教授”到“教授”,再初始工资上增加900元。代码如下:

展示初始的教师T表如下:

执行从“讲师”到“副教授”过程,并且查看结果:

结果如下,可以看出正常运转:

执行从“副教授”到“教授”过程,并且查看结果:

结果如下,可以看出正常运转:

总结与实验心得

(一)实验代码优化部分:

题目:修改SC表中一记录的学号,则要求检查表S中是否存在学号相同的记录,若存在则不许修改。

采用EXISTS语句进行比较效率更加高,因此将前边创建触发器中更新触发器中连接过程修改为之间判断是否存在的过程,提高了SQL代码的执行效率,在进行数据庞大的表时,效率更高,代码对比如下:

优化前:

优化后:

(二)总结

1.在声明变量时需要先确定变量的类型与确定其是为输入或输出变量,对变量进行命名时对变量进行标记输入或输出,并且尽量取名与字面意思相同的名称,便于程序的编写。

2.在定义存储过程时需要注意是否需要给查询输入的参数赋值默认值,有默认值的情况更利于存储过程的调用。

3. 对于调用存储过程时虽然不能使存储过程返回多条数据,但是通过运行调试发现,可以在存储过程中按照常规SQL语句执行,显示出多条数据在结果栏中。

修改存储过程如下:

调用存储过程并且返回查询结果如下:

       此过程并未进行赋值,也没有通过存储过程将查询结果数据传出,仅仅是在存储过程中通过查询语句得到查询表结果的页面显示上。具体的多行数据传出过程需要通过后续学习的游标才能真正完成实现。

实验体会存储过程与之前所学编程中函数的异同点:

不同方面:函数一般是之间包含在主程序中的,在同一界面下直接进行调用,而存储过程是单独作为打包文件存在数据库下。并且存储过程是返回对应参数,而函数只是返回值,同时存储过程功能比较强大,可以在其中直接进行表临时操作等。

相同方面:本质相同,均是对语句的打包执行,提高程序代码编写的效率且具有更强的安全性。

存储过程与触发器的差异:

存储过程主要是对于查询并且返回结果的语句执行的打包操作,需要再次执行调用才能完成某种查询执行操作,并且主要是针对查询操作返回参数结果。

触发器主要是实现级联更新、插入、删除等操作,是提前定义好的并且是针对特定的表,可以是针对单表内数据发生变化该表内其他数据对应属性值的变化,或者是单表数据发生变化后引起其他表数据相应的发生变化的过程,是一种数据发生变化后不需要调用而自动执行的过程。

触发器相对于外键的优势:功能比外键更加强大,外键仅仅是通过表的外连接,限制多表数据删除或者插入时的功能;而触发器除了包含外键的功能之外,同时还包含了域约束的效果,以及可以针对单表内进行数据级联更新变化,效果更加全面,而且多表之间也可以提前建立触发器关系,相应数据变化产生的其他数据对应的变化。

  • 9
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值