数据库原理及应用(第2版)习题参考答案 下载本文

A.在修课表的考试日期列上定义一个CHECK约束 B.在修课表上建立一个插入和更新操作的触发器 C.在学生表上建立一个插入和更新操作的触发器 D.在修课表的考试日期列上定义一个外码引用约束

·37· 9.设有教师表(教师号,教师名,职称,基本工资),其中基本工资的取值范围与教师职称有关,比如,教授的基本工资是6000~10000,副教授的基本工资是4000~8000。下列实现该约束的方法中,可行的是 C

A. 可通过在教师表上定义插入和修改操作的触发器实现 B. 可通过在基本工资列上定义一个CHECK约束实现 C. A和B都可以 D. A和B都不可以

10.设在SC(Sno,Cno,Grade)表上定义了触发器:

CREATE TRIGGER tri1 ON SC INSTEAD OF INSERT … 当执行语句:INSERT INTO SC VALUES('s001', 'c01',90)

会引发该触发器执行。下列关于触发器执行时表中数据的说法,正确的是 D A.SC表和INERTED表中均包含新插入的数据 B.SC表和INERTED表中均不包含新插入的数据

C.SC表中包含新插入的数据,INERTED表中不包含新插入的数据 D.SC表中不包含新插入的数据,INERTED表中包含新插入的数据 11.设在SC(Sno,Cno,Grade)表上定义了触发器:

CREATE TRIGGER tri1 ON SC AFTER INSERT … 当执行语句:INSERT INTO SC VALUES('s001', 'c01',90)

会引发该触发器执行。下列关于触发器执行时表中数据的说法,正确的是 A A.SC表和INERTED表中均包含新插入的数据 B.SC表和INERTED表中均不包含新插入的数据

C.SC表中包含新插入的数据,INERTED表中不包含新插入的数据 D.SC表中不包含新插入的数据,INERTED表中包含新插入的数据

12.当执行由UPDATE语句引发的触发器时,下列关于该触发器临时工作表的说法,正确的是 C

A.系统会自动产生UPDATED表来存放更改前的数据 B.系统会自动产生UPDATED表来存放更改后的数据

C.系统会自动产生INSERTED表和DELETED表,用INSERTED表存放更改后的数据,用DELETED表存放更改前的数据

D.系统会自动产生INSERTED表和DELETED表,用INSERTED表存放更改前的数据,用DELETED表存放更改后的数据

13.下列关于游标的说法,错误的是 D

A.游标允许用户定位到结果集中的某行 B.游标允许用户读取结果集中当前行位置的数据 C.游标允许用户修改结果集中当前行位置的数据

D.游标中有个当前行指针,该指针只能在结果集中单向移动

14.对游标的操作一般包括声明、打开、处理、关闭、释放几个步骤,下列关于关闭游标的说法,错误的是

A.游标被关闭之后,还可以通过OPEN语句再次打开 B.游标一旦被关闭,其所占用的资源即被释放 C.游标被关闭之后,其所占用的资源没有被释放

37

B

·38· D.关闭游标之后的下一个操作可以是释放游标,也可以是再次打开该游标

二. 填空题

1.利用存储过程机制,可以_____数据操作效率。 提高

2.存储过程可以接受输入参数和输出参数,对于输出参数,必须用_____词来标明。 OUTPUT 3.执行存储过程的SQL语句是_____。 EXEC (EXECUTE)

4.调用存储过程时,其参数传递方式有_____和_____两种。按参数位置 按参数名 5.修改存储过程的SQL语句是_____。ALTER PROC

6.SQL Server支持两种类型的触发器,它们是_____触发型触发器和_____触发型触发器。 前 后 7.在一个表上针对每个操作,可以定义_____个前触发型触发器。 一

8.如果在某个表的INSERT操作上定义了触发器,则当执行INSERT语句时,系统产生的临时工作表是_____。 INSERTED

9.对于后触发型触发器,当触发器执行时,引发触发器的操作语句(已执行完/未执行)_____。 已执行完 10.对于后触发型触发器,当在触发器中发现引发触发器执行的操作违反了约束时,需要通过_____语句撤销已执行的操作。 ROLLBACK

11.打开游标的语句是_____。 OPEN cursor_name

12.在操作游标时,判断数据提取状态的全局变量_____。 @@fetch_status 四.上机练习

以下各题均利用第3、4章建立的Students数据库以及Student、Course和SC表实现。 1. 创建满足下述要求的存储过程,并查看存储过程的执行结果。 (1) 查询每个学生的修课总学分,要求列出学生学号及总学分。

create proc p1 as

select sno,SUM(credit) as 总学分

from SC join Course c on c.Cno=SC.Cno group by sno

(2) 查询学生的学号、姓名、修的课程号、课程名、课程学分,将学生所在系作为输入参数,默认值为“计算机

系”。执行此存储过程,并分别指定一些不同的输入参数值,查看执行结果。 create proc p2

@dept varchar(20) = '计算机系' as

select s.sno,sname,c.cno,cname,credit from Student s join SC on s.Sno=SC.Sno join Course c on c.Cno=SC.Cno

where Sdept = @dept 执行示例1:EXEC P2

执行示例2:EXEC P2 '通信工程系'

(3) 查询指定系的男生人数,其中系为输入参数,人数为输出参数。

create proc p3

@dept varchar(20),@rs int output as

select @rs = COUNT(*) from Student where Sdept = @dept and Ssex = '男'

38

(4) 删除指定学生的修课记录,其中学号为输入参数。

create proc p4 @sno char(7) as

delete from SC where Sno = @sno

(5) 修改指定课程的开课学期。输入参数为:课程号和修改后的开课学期。

create proc p5

@cno char(6),@x tinyint as

update Course set Semester = @x where Cno = @cno

2. 创建满足下述要求的触发器(前触发器、后触发器均可),并验证触发器执行情况。 (1) 限制学生的年龄在15~45之间。

create trigger tri1

on student after insert,update as

if exists(select * from inserted where sage not between 15 and 45) rollback

(2) 限制学生所在系的取值范围为{计算机系,信息管理系,数学系,通信工程系}

create trigger tri2

on student after insert,update as

if exists(select * from student where sdept not in ('计算机系','信息管理系','数学系','通信工程系'))

Rollback

(3) 限制每个学期开设的课程总学分在20~30范围内。

create trigger tri3

on course after insert,update as

if exists(select sum(credit) from course

where semester in (select semester from inserted ) having sum(credit) not between 20 and 30 ) Rollback

(4) 限制每个学生每学期选课门数不能超过6门(设只针对插入操作)。

create trigger tri4 on sc after insert as

if exists(select * from sc join course c on sc.cno = c.cno where sno in (select sno from inserted) group by sno,semester

39

·39· ·40· having count(*) > 6 ) rollback

3. 创建满足下述要求的游标,并查看游标的执行结果。

(1) 列出VB考试成绩最高的前2名和最后1名学生的学号、姓名、所在系和VB成绩。

declare @sno char(10),@sname char(10),@dept char(14),@grade char(4) declare c1 SCROLL cursor for select s.sno,sname,sdept,grade

from student s join sc on s.sno = sc.sno join course c on c.cno = sc.cno where cname = 'vb' order by grade desc open c1

print ' 学号 姓名 所在系 VB成绩'

print '---------------------------------------' fetch next from c1 into @sno ,@sname ,@dept ,@grade if @@FETCH_STATUS = 0

print @sno + @sname + @dept + @grade

fetch next from c1 into @sno ,@sname ,@dept ,@grade if @@FETCH_STATUS = 0

print @sno + @sname + @dept + @grade

fetch last from c1 into @sno ,@sname ,@dept ,@grade if @@FETCH_STATUS = 0

print @sno + @sname + @dept + @grade close c1 deallocate c1

(2) 列出每个系年龄最大的名学生的姓名和年龄,将结果按年龄降序排序。

declare @sname char(10),@age char(4),@dept char(20) declare c1 cursor for select distinct sdept from student open c1

fetch next from c1 into @dept while @@FETCH_STATUS = 0 begin

print @dept

declare c2 cursor for

select top 2 with ties sname,sage from student where sdept = @dept order by sage desc open c2

fetch next from c2 into @sname ,@age if @@FETCH_STATUS = 0 print @sname + @age fetch next from c2 into @sname ,@age if @@FETCH_STATUS = 0 print @sname + @age print '' close c2 deallocate c2

fetch next from c1 into @dept

40