视图、触发器、存储、安全等
实验要求
(1) 掌握视图的定义与操作
(2) 掌握对触发器的定义
(3) 掌握对存储过程的定义
(4) 掌握如何对用户进行授权和收回权限
(5) 掌握用户定义完整性的方法
(6) 写出实验报告
实验步骤
(1) 创建表的视图
(2) 利用视图完成表的查询
(3) 删除表的视图
(4) 创建触发器
(5) 创建存储过程
(6) 对用户进行授权和查询
(7) 用户定义完整性
视图
(1) 创建
创建 CS 系的视图 CS_View CS 系的视图 CS_View
遇到问题
’CREATE VIEW’ 必须是查询批次中的第一个语句
批处理必须以 CREATE 语句开始。也就是说一个查询分析器里面只有一个批处理语句才是规范的语法。 CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE SCHEMA、CREATE TRIGGER 和 CREATE VIEW 语句不能在批处理中与其他语句组合使用。
所有跟在该批处理后的其他语句将被解释为第一个 CREATE 语句定义的一部分。 之间加GO关键字 分批即可。
也可以重新建立一个查询来写这个批处理语句
go
create view CS_View
as
select *
from Student
where Sdept='CS'
with check option
(2) 查询
在视图 CS_View 上查询 CS 系选修了 1 号课程的学生
go
select cs_view.sno,sname,ssex,sage,cno
from CS_View,sc
where cs_view.sno=sc.sno and cno=1
(3) 创建 IS 系
创建 IS 系成绩大于 80 的学生的视图 IS_View
go
create view IS_View
as
select Student.Sno,Sname,cno,grade
from Student,sc
where Student.sno=sc.Sno and Grade>80
(4) IS_View查询
在视图 IS_View 查询 IS 系成绩大于 80 的学生
select *
from IS_View
where grade>80
(5) 删除
删除视图 IS_View
drop view IS_View
(6) 不同用户操作
利用可视化窗口创建 2 个不同的用户 U1 和 U2,利用系统管理员给 U1 授予 Student 表的
查询和更新的权限,给 U2 对 SC 表授予插入的权限。然后
再进入数据库S_T_的用户处设置权限
对U1用户查看属性
但是登陆时出现问题
进行以下操作,成功登录,将sql 2008中的配置也进行相关更改。解决方案参考来源
用 U1 登录,分别
- 1)查询学生表 的信息;
- 2)把所有学生的年龄增加 1 岁,然后查询;
- 3)删除 IS 系的学生;
- 4)查询 CS 系 的选课信息。
登录后只能查看到student表
1)and 2)
select *
from Student
update Student
set Sage+=1
select *
from Student
3)
delete
from Student
where Sdept='IS'
4)
select sc.Sno,sname,sc.Cno
from Student,sc
where Sdept='CS'and Student.Sno=sc.Sno
用 U2 登录,分别
- 1)在 SC 表中插入 1 条记录(‘200215122’,‘1’,75);
- 2)查询 SC 表的信息,
- 3)查询视图 CS_View 的信息。
insert into sc values('200215122','1',75)
select *
from sc
select *
from CS_view
(7) 收回权限
用系统管理员登录,收回 U1 的所有权限
(8) U1再查询
用 U1 登录,查询学生表的信息
(9) 系统管理员登录
用系统管理员登录
触发器
(10) 建立触发器
对 SC 表建立一个更新触发器,当更新了 SC 表的成绩时,
如果更新后的成绩大于等于95,则检查该成绩的学生是否有奖学金,如果奖学金是“否”,则修改为“是”。
如果修改后的成绩小于 95,则检查该学生的其他成绩是不是有大于 95 的,如果都没有,且修改前的成绩是大于 95 时,则把其奖学金修改为”否”。
然后进行成绩修改,并进行验证是否触发器正确执行。
对于update操作,会建立两个虚表deleted(更新前数据)和inserted(更新后数据),完成后将表student中的deleted数据删除,插入inserted数据
触发器我写得不是很好,希望有不足的地方能指出
go
create trigger sc_trigger on sc --对sc表建立触发器
after update--语法:{After|Instead of} {insert|update|delete}
as
begin --begin后面输入sql语句
update Student
set Scholarship='是'
where Sno in
(select sc.sno
from sc,inserted
where inserted.Grade>=95 and Student.sno=sc.Sno
and sc.sno =inserted.Sno and scholarship='否' )
update Student
set Scholarship='否'
where sno in
(select sc.sno from sc,inserted,deleted
/*修改后小于95*/
where inserted.Grade<95 and sc.sno =inserted.sno
/*大于95的数为0*/
and (select count(grade) from sc where Grade>=95 and sno = inserted.sno)<1
and deleted.grade>=95 --该学生修改前分数大于95
and sc.sno=Student.sno)
end
- 1)首先把某个学生成绩修改为 98,查询其奖学金。
- 2)再把刚才的成绩修改为 80, 再查询其奖学金。
update sc
set Grade=98
where sno='200215122' and cno=2
select scholarship
from Student
where sno='200215122'
update sc
set Grade=80
where sno='200215122' and cno=2
select scholarship
from Student
where sno='200215122'
(11) 删除触发器
drop trigger sc_trigger
删除刚定义的触发器
存储过程
- 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行
- 存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数、输出参数、返回单个或多个结果集以及返回值。
- 由于存储过程在创建时即在数据库服务器上进行了编译并存储在数据库中,所以存储过程运行要比单个的SQL语句块要快。同时由于在调用时只需用提供存储过程名和必要的参数信息,所以在一定程度上也可以减少网络流量、简单网络负担。
(12) 定义存储过程
定义一个存储过程计算 CS 系的课程的平均成绩和最高成绩,在查询分析器或查询编辑器中执行存储过程,查看结果。
格式:
go
create proc(全称procedure可以简写为proc) [存储过程的名字]
( [@参数1 参数类型1],[@参数2 varhcar(50)],[参数3 varchar(50)='小白'],
[参数4 int output] ) /*output加上output后表示该参数是返回的参数*/
as
SQL语句
use S_T_
if (object_id('cs_proc', 'P') is not null)
drop proc cs_proc --判断该存储过程是否不存在,存在则删除
go
create procedure cs_proc
as
select avg(grade) ,max(grade)
from sc,student
where sc.sno =student.sno and Sdept='CS'
go
execute cs_proc --调用
go
(13)
定义一个带学号为参数的查看某个学号的所有课程的成绩,查询结果要包含学生姓名。进行验证。
if (object_id('grade_proc', 'P') is not null)
drop proc grade_proc --判断该存储过程是否不存在,存在则删除
go
create procedure grade_proc( @sno_s varchar(10))
as
select sname,sc.sno,cno,grade
from Student,sc
where sc.sno=Student.sno and sc.Sno=@sno_s
go
declare @sno_in varchar(10)='200215122'
exec grade_proc @sno_s=@sno_in
go
(14) 函数
把上一题改成函数。再进行验证。
if OBJECT_ID(N'dbo.search') is not null
drop function dbo.Search
go
create function dbo.Search(@Stu_No varchar(10))
returns table
as
return
(select Sname,sc.sno,cno,Grade from Sc,Student where Student.Sno=Sc.Sno and Student.Sno=@Stu_No )
go
--调用一下函数查询学号为200215122的学生成绩
select * from dbo.Search('200215122')
安全(约束)
(15) 完整性约束
在 SC 表上定义一个完整性约束,要求成绩再 0-100 之间。定义约束前,先把某个学 生的成绩修改成 120,进行查询,再修改回来。定义约束后,再把该学生成绩修改为 120,然后进行查询
update sc
set grade =120
where sno='200215122' and cno =2;
select sno,cno,grade from sc
where sno='200215122' and cno =2;
update sc
set grade =80
where sno='200215122' and cno =2
alter table sc
add constraint c3 check(grade between 0 and 100)
update sc
set grade =120
where sno='200215122' and cno =2;
select sno,cno,grade from sc
where sno='200215122' and cno =2