《数据库原理与应用》(第三版)第12章 函数和游标 基础 习题参考答案

1.SQL Server 2012提供的日期和时间函数有哪些?
答:getdate、dateadd、datediff、datename、day、month、year

2.SQL Server 2012提供的类型转换函数有哪些?其语法格式分别是什么?
答:cast和convert

3.SQL Server 2012支持的用户自定义函数有几种?每一种函数的函数体是什么?返回值是什么?
答:标量函数、内联表值函数、多语句表值函数。
标量函数的函数体是可以是一系列SQL语句,返回值是一个标量值;
内联表值函数的函数体的一条查询语句,返回值是查询语句的执行结果(表);
多语句表值函数的函数体是一系列SQL语句,返回值是一个表。

4.利用系统提供的函数,完成下列操作:
(1)计算从2000年1月1日到当前日期的天数、月份数及年数。
答:select datediff(day,‘2000-1-1’,getdate()) 天数,
datediff(month,‘2000-1-1’,getdate()) 月份数,
datediff(year,‘2000-1-1’,getdate()) 年数

(2)分别计算系统当前日期加上40天和减去40天后的新日期。
答:select dateadd(day,40,getdate()) 加40天,
dateadd(day,-40,getdate()) 减40天

(3)得到“You are a student”字符串中从11开始,长度为7的子串。
答:select substring(‘You are a student’,11,7)

(4)分别计算“You are a student”和“我们是学生”字符串中字符的个数。
答:select len(‘You are a student’),len(‘我们是学生’)

(5)分别得到字符串“I am a teacher and you are students” 中左边14个和右边16个字符组成的字符串。
答:select left(‘I am a teacher and you are students’,14),
right(‘I am a teacher and you are students’,16)

5.游标的作用是什么?其包含的内容是什么?
答:游标提供了对查询结果集的定位操作功能。其包含内容是查询结果集。

6.如何判断游标当前行指针指到了游标结果集之外?
答:使用@@fetch_status全局变量。

7.使用游标需要几个步骤?分别是什么?其中哪个步骤是真正产生游标结果集?
答:五个主要。步骤,定义游标、打开游标、处理数据、关闭游标、释放游标资源。打开游标。

8.关闭游标和释放游标在功能上的差别是什么?
答:关闭游标并不真实释放游标占用的资源,也就是游标的定义还存在,还可以通过open语句再次打开该游标进行处理。释放游标是释放了与该游标有关的一切资源。

上机练习
1.创建满足下述要求的用户自定义标量函数。
(1)查询指定学生已经得到的修课总学分(考试及格的课程才能拿到学分),学号为输入参数,总学分为函数返回结果。并写出利用此函数查询9512101学生的姓名、所修的课程名、课程学分、考试成绩以及拿到的总学分的SQL语句。
答:
CREATE FUNCTION dbo.f_Sum_Credit(@sno char(7))
RETURNS int
AS
BEGIN
DECLARE @x int
SELECT @x = sum(credit) FROM SC join course c on c.cno = sc.cno
WHERE SNO = @sno and grade >= 60
RETURN @x
END
调用:
SELECT Sname, cname,credit, dbo.f_Sum_Credit(s.Sno) AS 总学分
FROM Student s join sc on s.sno = sc.sno
join course c on c.cno = sc.cno
WHERE s.Sno = ‘9512101’

(2)查询指定系在指定课程(课程号)的考试平均成绩。
答:
CREATE FUNCTION dbo.f_Avg_Grade(@dept varchar(20),@cno varchar(10))
RETURNS int
AS
BEGIN
DECLARE @x int
SELECT @x = avg(grade) FROM SC join student s on s.sno = sc.sno
where sdept = @dept and cno = @cno
RETURN @x
END
(3)查询指定系的男生中选课门数超过指定门数的学生人数。
答:
CREATE FUNCTION dbo.f_rs(@dept varchar(20),@cnt int)
RETURNS int
AS
BEGIN
DECLARE @x int
SET @x = (select count() from student
where sdept = @dept and ssex = ‘男’
and sno in (
select sno from sc group by sno having count(
) > @cnt ))
RETURN @x
END

2.创建满足下述要求的用户自定义内联表值函数。
(1)查询选课门数在指定范围内的学生的姓名、所在系和所选的课程。
答:
CREATE FUNCTION dbo.f_count(@x int)
RETURNS TABLE
AS
RETURN (
SELECT Sname, sdept, cno
FROM Student S JOIN SC ON S.Sno = SC.Sno
WHERE s.sno in (
select sno from sc
group by sno
having count(*) > @x ))

(2)查询指定系的学生考试成绩大于等于90的学生的姓名、所在系、课程名和考试成绩。并写出利用此函数查询计算机系学生考试情况的SQL语句,只列出学生姓名、课程名和考试成绩。
答:
CREATE FUNCTION dbo.f_dept(@dept varchar(20))
RETURNS TABLE
AS
RETURN (
SELECT Sname, sdept, cname,grade
FROM Student S JOIN SC ON S.Sno = SC.Sno
join course c on c.cno = sc.cno
WHERE sdept = @dept and grade >= 90 )
调用:
SELECT sname,cname,grade FROM dbo.f_dept(‘计算机系’)

3.创建满足下述要求的用户自定义多语句表值函数。
(1)查询指定系年龄最大的前2名学生的姓名和年龄,包括并列的情况。
答:
CREATE FUNCTION f_TopAge(@dept varchar(20))
RETURNS @retSType table(
Sname char(10),
Sage int )
AS
BEGIN
INSERT INTO @retSType
SELECT top 2 with ties Sname, Ssex
FROM Student
WHERE Sdept = @dept
order by sage desc
RETURN
END
(2)查询指定学生(姓名)的考试情况,列出姓名、所在系、修的课程名和考试情况,其中考试情况列的取值为:如果成绩大于等于90,则为“优”;如果成绩在8089,则为“良好”;如果成绩在7079,则为“一般”;如果成绩在60~69,则为“不太好”;如果成绩小于60,则为“很糟糕”。并写出利用此函数查询李勇的考试情况的SQL语句。
答:
CREATE FUNCTION f_Exam(@name varchar(20))
RETURNS @retSType table(
Sname char(10),
Sdept varchar(20),
Cname varchar(20),
grade varchar(8) )
AS
BEGIN
INSERT INTO @retSType
SELECT Sname, Sdept,Cname,case
when grade >= 90 then ‘优’
when grade between 80 and 89 then ‘良好’
when grade between 70 and 79 then ‘一般’
when grade between 60 and 69 then ‘不太好’
else ‘很糟糕’
end
FROM Student s join sc on s.sno = sc.sno
join course c on c.cno = sc.cno
WHERE Sname = @name
RETURN
END
调用:
SELECT * FROM f_Exam(‘李勇’)

4.创建满足下述要求的游标。
(1)查询VB课程的考试情况,并按如下形式显示结果数据:
选了VB课程的学生情况:
姓名 所在系 成绩
李勇 计算机系 86
刘晨 计算机系 78
吴宾 信息系 75
张海 信息系 68
答:
declare @sname char(10),@dept char(14),@grade int
declare c1 SCROLL cursor for
select 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 @sname ,@dept ,@grade
while @@FETCH_STATUS = 0
begin
print @sname + @dept + cast(@grade as char(3))
fetch next from c1 into @sname ,@dept ,@grade
End
close c1
deallocate c1
(2)统计每个系的男生人数和女生人数,并按如下形式显示结果数据。
系名 性别 人数

计算机系 男 2
计算机系 女 1
数学系 男 1
数学系 女 1
信息系 男 2
信息系 女 1
答:
declare @dept char(13),@sex char(8),@cnt int
declare c1 cursor for
select sdept,ssex,count(*) from student
group by sdept,ssex
order by sdept

print ‘系名 性别 人数’
print ‘=======================’

open c1
fetch next from c1 into @dept,@sex,@cnt
while @@FETCH_STATUS = 0
begin
print @dept + @sex + cast(@cnt as char(4))
fetch next from c1 into @dept,@sex,@cnt
end
close c1
deallocate c1

(3)列出每个系的学生信息,要求首先列出一个系的系名,然后在该系名下列出本系学生的姓名和性别;再列出下一个系名,然后在此系名下再列出该系的学生姓名和性别;以此类推,直至列出全部系。要求按如下形式显示结果数据:
计算机系学生:
李勇 男
刘晨 男
王敏 计算机系

数学系学生:
钱小平 数学系
王大力 数学系

信息系学生:
张立 信息系
吴宾 信息系
张海 信息系

答:
declare @sname char(10),@sex 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 rtrim(@dept) + ‘学生:’
declare c2 cursor for
select sname,ssex from student where sdept = @dept
open c2
fetch next from c2 into @sname ,@sex
while @@FETCH_STATUS = 0
begin
print @sname + @sex
fetch next from c2 into @sname ,@sex
end
close c2
deallocate c2
print ‘==============’
fetch next from c1 into @dept
end
close c1
deallocate c1

发布了750 篇原创文章 · 获赞 471 · 访问量 32万+

猜你喜欢

转载自blog.csdn.net/weixin_43336281/article/details/105500572