实验1 认识SQL Server 2106 的运行环境
实验目的:掌握SQL Server Management Studio集成环境的构成和基本操作,熟悉服务器管理和基本操作,熟悉联机丛书与教程的使用。
实验步骤:
(1)SQL Server Management Studio的启动和退出
1)启动SQL Server Management Studio
2)连接服务器选择
3)连接服务器的属性设置
4)身份验证选择
5)连接
6)退出SQL Server Management Studio
(2)SQL Server Management Studio的基本操作
1)菜单栏的操作
2)工具栏的操作
3)“已注册的服务器”窗口
4)“对象资源管理器”窗口
5)“文档”窗口
6)属性窗口
7)模板资源管理器
(3)新建查询
1)打开查询编辑器代码窗口
2)输入一条SQL查询语句
3)执行该脚本
(4)注册SQL Server 2016服务器
1)打开“已注册的服务器”窗口
2)弹出“新建服务器注册”对话框
3)输入服务器名称及其身份验证方式
4)在“已注册的服务器名称”文本框中输入管理的服务器名称,可以使用默认的服务器实例名,也可以重新命名。
5)单击测试按钮,成功后单击确定返回“新建服务器注册”对话框。
6)在“新建服务器注册”对话框中切换至“连接属性”选项卡,可设置注册服务器的相关属性。
7)单击保存按钮,完成服务器注册操作。
(5)启动和停止SQL Server 2016服务器
1)使用SQL Server配置管理器完成。
2)使用SQL Server Management Studio完成。
3)使用SQL Server服务完成
(6)配置SQL Server 2016服务器
启动SQL Server Management Studio,在对象资源管理器中单击已连接的服务器,打开服务器属性窗口完成配置。
(7)SQL Server 2016联机丛书和教程的使用
(8)理解model数据库的作用
1)在model数据库中创建模式S_T,用户表S_T.s、S_T.sc和S_T.c(表结构参照上学期数据库原理教材中表结构)
2)创建数据库student,查看该数据库中的数据表和模式。
2)为student数据的s表键入自己的信息
实验2 创建与管理数据库
创建与管理数据库
(1) 利用Transact-SQL语句创建一个名为CPChistory的数据库。该数据库的主数据库文件逻辑名称为CPChistory,初始大小为10MB,最大尺寸为无限大,增长速度为10%;数据库的日志文件逻辑名称为CPChistory_log,初始大小为1MB,最大尺寸为5MB,增长速度为1MB。存放路径为D:\DATA\,其他均采用默认设置。
(2) 利用Transact-SQL语句增加文件组filegroup1,添加次要数据文件CPChistory2放入文件组filegroup1中,添加逻辑名称为CPChistory2_log的日志文件,文件均放在D:\DATA\目录下。
(3) 利用Transact-SQL语句创建数据库test,采用默认参数。若该数据库已存在,则删除后重建。
if exists(select * from sys.databases where name = 'test')
drop database test
create database test
(4)修改数据库test,将数据文件的逻辑文件名修改为“测试数据”,操作系统文件名修改成D:\DATA\test.MDF。将事务日志文件的逻辑文件名修改为“测试数据日志”,操作系统文件名修改成D:\DATA\test_log.LDF。并且为数据库新增一个逻辑名为“测试数据2”的次要数据文件。
(5)利用SQL Server Management Studio将test数据库分离后重新附加到当前SQL Server实例中。
(6)利用Transact-SQL语句将test数据库重命名为“测试”,调用系统存储过程将“测试”重命名为test。
(7)利用Transact-SQL语句为数据库CPChistory和test创建快照。
(8)利用Transact-SQL语句删除创建的数据库CPChistory和test。
alter database CPChistory remove file CPChistory2
实验3.1 表的创建与维护
实验三 表的创建与维护
(1)利用SQL Server Management Studio自定义数据类型sex_type,类型为nchar(1);
(2)利用Transact-SQL语句创建表“人物”“部队”“战役”“属于”(表结构见作业的参考答案),性别属性的数据类型设置为sex_type),注意主外键的设置。
(3)利用Transact-SQL语句修改为表“人物”增加属性“民族”,类型为nchar(8),设置not null 约束。
(4)利用Transact-SQL语句为表“人物”的姓名属性增加唯一约束;
为“战役”表的“胜败”列创建check约束,规定取值为“胜”“败”“平”。
(4)为“人物”表插入如下数据:1)将插入的信息输出到表变量@people;2)浏览表变量中的信息。
编号 姓名 出生年月 性别 党派 民族
2 周恩来 1898-3-5 男 中国共产党 汉族
3 朱德 1886-12-1 男 中国共产党 汉族
4 张闻天 1900-8-30 男 中国共产党 汉族
5 王稼祥 1906-8-15 男 中国共产党 汉族
6 刘伯承 1892-12-4 男 中国共产党 汉族
为“属于”表输入如下数据:
人物编号 部队编号 开始时间 结束时间 任职
6 KR129 1937-8-25
(5)根据“人物”和“属于”两个关系,在“属于”关系中将刘伯承在KR129师的任职改为“师长”。
(7)创建excle文档,数据结构如下,然后将其导入数据库,建立“参战”表。
部队编号 战役名称 参加人数 损失人数
KR129 淞沪会战 NULL NULL
KR120 百团大战 400000 17000
选做:通过学习联机帮助完成以下操作:
创建student表(表结构如表4-8(82页)),使其按照学号进行分区,N0001-N0400放在primary文件组,N0401-N800放在filegroup1,N800以上的放在filegroup2
命令提示:
1.CREATE PARTITION FUNCTION
2.CREATE PARTITION SCHEME
3.CREATE TABLE
实验3.2 表的创建与维护
实验三
(1)利用SQL Server Management Studio自定义数据类型grade_type,类型为numeric(5,2)。
(2)利用Transact-SQL语句创建表student(表结构如表4-8(82页))、course(表结构如表4-9)和表score(表结构如表4-10,usually和final属性的数据类型设置为grade_type),注意主外键的设置。
(3)向student表输入如下数据
studentno sname sex birthdate classno
1 张三 男 2000-3-7 1
2 李四 男 2002-6-1 2
3 王五 男 2001-7-7 2
4 赵华 女 2001-8-21 3
(4)查询student表,输出前3条记录。
(5)修改score表,将usually改为“平时成绩”,并增加计算列“总评”,使其值为平时成绩的40%加上final的60%。
alter table score
add 总评 as (平时成绩 * 0.4 + final * 0.6) persisted
(6)阅读下面语句,写出每个语句的作用
declare @var_student table(sno nchar(11));
声明表变量@var_student
Insert top(3) into @var_student select sno from student;
插入数据,同时将插入行的前三行放入表变量@var_student中
Select * from @var_student table;
查询表变量中的值
实验4.1 Transact-SQL语句基础
实验四-1 Transact-SQL语句基础
- 变量的应用
定义变量 @sno CHAR(8)
@name VARCHAR(10)
@sex NCHAR(2)
@birthday DATETIME
使用set 和 select 用自己的信息赋值
打印 @sno+@name+@sex
打印 @birthday
declare @sno char(12), @name varchar(10), @sex nchar(2), @birthday datetime
set @sno = '202012304054'
set @name = '洋溢'
set @sex = '女'
set @birthday = '2002-8-4'
select @sno+@name+@sex
select @birthday
(2)运算符的应用
–算术运算符
打印 当前日期后100天的日期
打印 123+23%10/7+(17-6)*2.5
print dateadd(day, 100, getdate())
print 123+23%10/7+(17-6)*2.5
–字符串连接运算符
定义变量 @A CHAR(5)
@B VARCHAR(5)
@C INT
@D DECIMAL(5,2)
赋值 @A=‘123’
@B=‘456.5’
@C=123
@D=456.5
打印 @A+@B
@A+@D
@C+@D
赋值 @A=‘数据库’
@B=‘程序开发’
打印 @A+@B
打印 @A+@D
declare @A CHAR(5), @B VARCHAR(5), @C INT, @D DECIMAL(5,2)
set @A = '123'
set @B = '456.5'
set @C = 123
set @D = 456.5
print @A + @B
print @A + @D
print @C + @D
set @A = '数据库'
set @B = '程序开发'
print @A + @B
print @A + cast(@D as VARCHAR(10))
print @A + @D
–位运算符
定义变量 @A INT
@B INT
赋值 @A=5
@B=12
打印 @A&@B
@A|@B
@A^@B
~@A
declare @A INT, @B INT
set @A = 5
set @B = 12
print @A & @B
print @A | @B
print @A ^ @B
print ~ @A
–(3)系统函数的应用
–数学函数
打印 CEILING(16.3)
CEILING(-16.8)
CEILING(0.0)
FLOOR(16.3)
FLOOR(-16.8)
FLOOR(0.0)
ROUND(123.456,2)
ROUND(123.456,-1)
ROUND(123.456,-2)
ROUND(123.456,-4)
ROUND(175.86,0)
ROUND(175.86,0,1)
print CEILING(16.3)
print CEILING(-16.8)
print CEILING(0.0)
print FLOOR(16.3)
print FLOOR(-16.8)
print FLOOR(0.0)
print ROUND(123.456,2)
print ROUND(123.456,-1)
print ROUND(123.456,-2)
print ROUND(123.456,-4)
print ROUND(175.86,0)
print ROUND(175.86,0,1)
–转换函数
定义变量 @count INT
@date DATETIME
赋值 @count=255
@date=GETDATE()
打印 @count转换为字符串打印
打印’2016-12-25’后100天的时间(转换成日期型打印)
将@date转换成字符串打印
declare @count int, @date datetime
set @count = 255
set @date=getdate()
print cast(@count as varchar(12))
print dateadd(day, 100, 2016-12-25)
print cast(@date as varchar(12))
–字符串函数
定义变量 @str NCHAR(25)
赋值 @str=‘SQL SERVER 2008数据库应用与开发’
打印 @str 的长度
‘数据库’在@str中的起始位置
将@str中’开发’替换成’设计’)
declare @str nchar(25)
set @str = 'SQL SERVER 2008数据库应用与开发'
print len(@str)
print replace(@str, '开发', '设计')
实验4.2 控制流语句编程
实验四 控制流语句编程
1.编程求50~100之间所有能被3整除的奇数之和。(必做)
declare @sum int = 0
declare @n int = 50
while @n >= 50 and @n <= 100
begin
if @n % 3 = 0
set @sum = @sum + @n
set @n = @n + 1
end
print @sum
2.编写程序根据姓名查询teaching数据库(相关表信息见教材82-88页表4-8至表4-13,下同)中学生的基本信息和选课信息,学生姓名通过变量输入。对不存在的学生,打印提示信息。(提示:定义局部变量@same,将自己的姓名赋值给局部变量@same)(必做)
declare @same nchar(8) = '竹云泽'
if exists (select * from student where @same = sname)
begin
select distinct student.*, course.*
from student, course, score
where student.sname = @same and student.studentno = score.studentno and score.courseno = course.courseno
end
else
print '不存在' + rtrim(@same)+ '该同学信息'
- 编写程序查询所有学生选修课程的期末成绩和对应等级,如学生未选修任何课程则输出提示信息。(提示:使用case语句根据成绩来确定其等级,如果没有成绩则打印未选修)(必做)
(期末成绩>=90 对应等级为“优”,
90>期末成绩>=80 对应等级为“良”,
80>期末成绩>=70 对应等级为“中”,
70>期末成绩>=60 对应等级为“及格”,
期末成绩<60 对应等级为“不及格”)
select distinct studentno '学号', courseno '课程号', final '分数' ,
case
when final >= 90 then '优'
when final >= 80 then '良'
when final >= 70 then '中'
when final >= 60 then '及格'
when final < 60 then '不及格'
when final is null then '未选修'
end '等级'
from score
- 编写程序判断字符变量@ch中存放的是字母字符、数字字符还是其他字符,并输出相关信息。(必做)
declare @ch char = 'a'
if upper(@ch) >= 'A' and upper(@ch) <= 'Z'
print @ch + '是字母字符'
else if @ch >= '0' and @ch <= '9'
print @ch + '是数字字符'
else
print @ch + '是其他字符'
- 建立数据库charge,建立数据表water(用户编号,年,月,用水量)。(要求利用case 语句)
为鼓励居民节约用水,很多城市实行了阶梯水费的收缴形式。以桂林为例,居民生活用水费的收费标准为,每户月用水量,在32立方米以内时,每立方米收费1.47元,超过32立方米但小于48立方米时,超出的部分,按每立方米2.21元收费,超过48立方米时,超出的部分,按每立方米2.94元收费。编写程序,输出用户用水情况,并根据用户的用水量,计算并显示其对应的水费。
select distinct 用户编号, 用水量,
case
when 用水量 <= 32 then 用水量 * 1.47
when 用水量 > 32 and 用水量 <= 48 then 32 * 1.47 + (用水量 - 32) * 2.21
when 用水量 > 48 then 32 * 1.47 + (48 - 32) * 2.21 + (用水量 - 48) * 2.94
end 水费
from water
- 给定一行字符串,分别统计出其中英文字母、空格、数字和其它字符的个数。(要求运用字符串函数)
declare @pos bigint = 1, @len bigint, @char nvarchar(1), @text nvarchar(max)
declare @letters bigint = 0, @numbers bigint = 0, @spaces bigint = 0, @others bigint = 0
set @text = '123q we ! @ #'
set @len = len(@text)
while @pos <= @len
begin
set @char = substring(@text, @pos, 1)
if @char = ' '
set @spaces += 1
else if upper(@char) >= 'A' and upper(@char) <= 'Z'
set @letters += 1
else if @char >= '0' and @char <= '9'
set @numbers += 1
else
set @others += 1
set @pos = @pos + 1 --
end
print 'letters:' + cast(@letters as nvarchar(2))
print 'numbers:' + cast(@numbers as nvarchar(2))
print 'spaces:' + cast(@spaces as nvarchar(2))
print 'others:' + cast(@others as nvarchar(2))
- 打印出如下图案(菱形)(要求利用while语句)
declare @a int = 1, @b int = 7
while @a < @b
begin
if @a % 2 = 1
print space((@b - @a) / 2) + replace(space(@a), ' ', '*') + space((@b - @a) / 2)
set @a += 1
end
while @a <= @b
begin
if @a % 2 = 1
print space((@b - @a) / 2) + replace(space(@a), ' ', '*') + space((@b - @a) / 2)
set @a -= 1
if @a < 0
break
end
- 编写程序将十进制整数转换为二进制字符串后输出。(选做)
declare @ch nchar(10) = ' ', @n int = 10, @a int
while @n <> 0
begin
set @a = @n % 2
set @n = @n / 2
set @ch = char(48 + @a) + @ch
end
print @ch
- 编写程序求解如下分数序列的前n项之和并打印输出结果,n由变量输入。(选做)
declare @n float = 2, @sum float = 0, @t float, @分子 float = 2, @分母 float = 1
set @t = @n
while @t > 0
begin
set @sum = @sum + @分子 / @分母
set @分子 = @分子 + @分母
set @分母 = @分子 - @分母
set @t -= 1
end
print @sum
实验5 针对Teaching数据库,完成以下查询
实验五
针对Teaching数据库,完成以下查询:
(1)查询选修课程且期末成绩不为空的学生人数。
select distinct count(studentno) 人数
from course, score
where course.courseno = score.courseno and score.final is not null and course.courseno in (
select courseno
from course
where type = '选修'
)
(2)查询所有Email使用126邮箱的学生的学号、姓名和电子邮箱地址。
select studentno, sname, Email
from student
where Email like '%126%'
(3)查询每名学生的学号、选修课程数目、总成绩,并将查询结果存放到生成的“学生选课统计表”中。
if exists (select * from sys.objects where name = '学生选课统计表')
drop table 学生选课统计表
select studentno, count(*) '学生选课数目', sum(final) '总成绩' into 学生选课统计表
from score
group by studentno
select * from 学生选课统计表
(4)查询选修’c05109’课程,并且期末成绩在前5名的学生学号、课程号和期末成绩。
select top(5) studentno, courseno, final
from score
where courseno = 'c05109'
order by final desc
(5)查询教授两门及以上课程的教师编号、课程编号和任课班级。
select teacherno, courseno, classno
from teach_class
where teacherno in (
select teacherno
from teach_class
group by teacherno
having count(courseno) >= 2
)
(6)查询课程编号以’c05’开头,被三名及以上学生选修,且期末成绩的平均分高于75分的课程号、选修人数和期末成绩平均分,并按平均分的降序排序。
select courseno, count(studentno) 选修人数, avg(final) 期末平均分
from score
where courseno like 'c05%' and final is not null
group by courseno
order by avg(final) desc
(7)查询每个教师的授课门数及所有老师的授课总门数。
select teacherno, count(courseno) 授课门数
from teach_class
group by teacherno
select count(courseno) 授课总门数
from teach_class
(8)P161(4)按性别分组,求出student表中每组学生的平均年龄。
P161(5)利用现有的表生成新表,新表中包括学号、学生姓名,课程号和总评成绩。其中,总评成绩=final * 0.8 + daily * 0.2。
select student.studentno, sname, courseno, final * 0.8 + usually * 0.2 总评
into student_score
from student, score
where student.studentno = score.studentno
select * from student_score
(9)P161(6)统计每个学生的期末成绩平均分。
select studentno, avg(final)
from score
group by studentno
(10)P161(7)输出student表中年龄最大男生的所有信息。
select *
from student
where sex = '男' and datediff(year, birthday, getdate()) >= (
select max(datediff(year, birthday, getdate()))
from student
where sex = '男'
)
实验6.1 利用Teaching数据库完成以下查询
实验六-1
利用Teaching数据库完成以下查询。
(1)查询教师基本信息和教授课程信息,其中包括未分配课程的教师信息。
select teacher.*, teach_class.courseno
from teacher
left join teach_class on teacher.teacherno = teach_class.teacherno
left join course on teach_class.courseno = course.courseno
(2)查询所有班级期末平均成绩的最高分,并将其赋值给变量,通过PRINT语句输出。
declare @max numeric(6,2)
select @max = max(平均分)
from(
select classno as 班级号, avg(final) as 平均分
from score
join student on( score.studentno=student.studentno)
where final is not null
group by classno)t
print '所有班级期末平均成绩的最高分:'+cast(@max as varchar(6))
(3)查询16级学生的学号、姓名、课程名及学分。
select student.studentno,sname,cname,credit
from score
join student on student.studentno = score.studentno
join course on course.courseno= score.courseno
where student.studentno like '16%'
(4)P186 3(2)
select distinct student.studentno,student.sname,
course.cname,score.final * 0.9 + score.usually * 0.1 as '总评'
into student_course
from student,course,score
where student.studentno = score.studentno
and course.courseno = score.courseno
select * from student_course
(5)P186 3(3)
select student.studentno, count(*) as '课程门数'
from score
join student on student.studentno = score.studentno
where score.final > 75
group by student.studentno
或者
select student.studentno, count(*) as '课程门数'
from student,score
where score. final > 75 and student.studentno = score.studentno
group by student.studentno
(6)P186 3(4)
select *
from student
where sex='男' and datediff(day, birthday, getdate()) > (
select avg(datediff(day, birthday, getdate()))
from student
where sex ='女')
(7)P186 3(5)
select student.studentno,student.sname,sum(credit) 学分
from student
join score on student.studentno = score.studentno
join course on course.courseno= score.courseno
where score.final > 60
group by student.studentno,student.sname
(8)P186 3(8)
select studentno, count(*) num into cnt
from score
group by studentno
select distinct student.studentno,sname,phone,Email
from student
join score on student. studentno = score.studentno
join cnt on student.studentno = cnt.studentno
where score.final < 60 or num< 3
实验6.2 游标
实验六-2游标
(1)使用游标输出学生姓名、选修课程名称和期末考试成绩,按如下格式输出。
学生姓名 课程名称 期末成绩
XXXX XXXX XXXX
XXXX XXXX XXXX
XXXX XXXX XXXX
print'姓名 课程 期末成绩'
print('-------------------------------------------')
declare @sname varchar(20),@cname varchar(20),@final varchar(20)
declare stu_cursor cursor
for select sname,cname,final
from student a join score b on a.studentno=b.studentno join course c on b.courseno=c.courseno
open stu_cursor
fetch next from stu_cursor into @sname,@cname,@final
while @@fetch_status=0
begin
print @sname+@cname+@final
fetch next from stu_cursor into @sname,@cname,@final
end
close stu_cursor
deallocate stu_cursor
(2)使用游标计算学生期末成绩的等级(大于等于90为优秀,大于等于80小于90为良好,大于等于70小于80为中等,大于等于60小于70为及格,小于60为不及格)。
①在score表中新增等级字段level。
②使用游标计算学生期末成绩的等级,并更新level列。
③查看使用游标修改数据表后的结果。
declare @usually numeric(6, 2),@final numeric(6, 2), @leve nchar(6)
declare score_cursor cursor
for select final,usually,leve from score
open score_cursor
fetch next from score_cursor into @final,@usually, @leve
while @@fetch_status=0
begin
select @final, @usually, @leve
if(@final * 0.9 + @usually * 0.1 >= 90)
update score set leve='优秀'
where current of score_cursor
else if(@final * 0.9 + @usually * 0.1 >= 80)
update score set leve='良好'
where current of score_cursor
else if(@final * 0.9 + @usually * 0.1 >= 70)
update score set leve='中等'
where current of score_cursor
else if(@final * 0.9 + @usually * 0.1 >= 60)
update score set leve='及格'
where current of score_cursor
else
update score set leve='不及格'
where current of score_cursor
fetch next from score_cursor into @final,@usually, @leve
end
close score_cursor
deallocate score_cursor
(3)开课表(开课号、课程号、教师号、开课地点、开课学年、开课学期、开课周数、开课时间、限选人数、已选人数)选课表(学号、开课号、成绩)
题目:开课表中,由于每一个开课号有人数限制,当学生选课确定后,需和该开课号的限选人数相对比,如果没有超过限选人数,则已选人数修改为实际选课人数,否则打印“这个开课计划选择的人数已经超过限选人数,请调整!”。使用游标逐个检查并修改每个开课号在选课表中的学生选修人数,并显示输出。
declare @courseno nchar(11), @stunumber tinyint, @total tinyint
declare course_cursor cursor
for select courseno,period from course
open course_cursor
fetch next from course_cursor into @courseno,@stunumber
while @@fetch_status=0
begin
select @courseno,@stunumber
--定义内层游标
declare stu_cursor cursor
for
select count(studentno) as 'total'
from score
where score.courseno = @courseno
group by courseno
open stu_cursor
fetch next from stu_cursor into @total
while @@fetch_status=0
begin
if @total > @stunumber print '这个开课计划选择的人数已经超过限选人数,请调整!'
if @total < @stunumber
update course set period=@total
where current of course_cursor
fetch next from stu_cursor into @total
end
close stu_cursor
deallocate stu_cursor
--内层游标结束
fetch next from course_cursor into @courseno,@stunumber
end
close course_cursor
deallocate course_cursor
(4)学生选课管理中,当学生选修某门课分数不低于60时才能获得学分。检查学生获得的学分数是否正确,如果不正确,则进行修改。
学生表(学号,姓名,性别,专业,院系,累计学分)
选课表 (学号、开课号、成绩)
开课表(开课号、课程号、教师号、开课地点、开课学年、开课学期、开课周数、开课时间、限选人数、已选人数)
课程表(课程号、课程名称、学分)
–生成绩点表
select distinct student.studentno,student.sname,course.cname,
score.final * 0.9+ score.usually * 0.1 as '总评',
(score.final * 0.9+ score.usually * 0.1)/10-5 as 'credit' into student_corse2
from student,course,teach_class,score
where student.studentno = score.studentno and course.courseno = score.courseno
select *
from student_corse2
--检查学分
declare @总评 numeric(6, 2),@credit numeric(6, 2)
declare score_cursor cursor
for select 总评, credit from student_corse2
open score_cursor
fetch next from score_cursor into @总评, @credit
while @@fetch_status=0
begin
select @总评, @credit
if(@总评 < 60)
update student_corse2 set credit=0
where current of score_cursor
fetch next from score_cursor into @总评, @credit
end
close score_cursor
deallocate score_cursor
(5)某同学建立了学生表,由于没有设置主键,因此表中存在很多重复的记录。现在需要对表中数据进行清洗,去掉重复记录,对于重复的取值,仅保留一条记录。请利用游标完成。
declare @studentno1 nchar(11),@studentno2 nchar(11)
declare stu_cursor1 cursor
for select studentno from student
open stu_cursor1
fetch next from stu_cursor1 into @studentno1
while @@fetch_status=0
begin
select @studentno2
--定义内层游标
declare stu_cursor2 cursor
for
select studentno as 'studentno2'
from student
open stu_cursor2
fetch next from stu_cursor2 into @studentno2
while @@fetch_status=0
begin
if(@studentno1 = @studentno2)
delete from student where studentno = @studentno2
fetch next from stu_cursor2 into @studentno2
end
close stu_cursor2
deallocate stu_cursor2
--内层游标结束
fetch next from stu_cursor1 into @studentno1
end
close stu_cursor1
deallocate stu_cursor1
(6)针对已经建好如下的本地游标和全局游标,利用sp_cursor_list函数返回所有可视的全局游标列表及其特性,利用sp_describe_cursor_columns和sp_describe_cursor_tables函数返回所有可视的本地游标的情况。
declare @teacherno nchar(6),@tname nchar(8)
declare teacher_cursor cursor
for select teacherno,tname FROM teacher
declare @teacher_cursor cursor
exec teaching.dbo.sp_cursor_list
@cursor_return = @teacher_cursor output,cursor_scope = 2
open teacher_cursor
fetch next from teacher_cursor into @teacherno,@tname
while @@fetch_status = 0
begin
fetch next from teacher_cursor
end
close @teacher_cursor
deallocate @teacher_cursor
--sp_describe_cursor_columns
declare @x_cursor cursor
declare student_cursor cursor
for
select studentno, sname
from student
open student_cursor
EXEC sp_describe_cursor_columns @cursor_return=@x_cursor OUTPUT, @cursor_source=N'global', @cursor_identity= N'student_cursor'
fetch next from student_cursor --使得@@FETCH_STATUS=0
while @@FETCH_STATUS=0
begin
fetch next from @x_cursor
end
close @x_cursor
deallocate @x_cursor
deallocate student_cursor
1)本地游标cur_score,输出学生姓名、选修课程名称和期末考试成绩
print'姓名 课程 期末成绩'
print('-------------------------------------------')
declare @sname varchar(20),@cname varchar(20),@final varchar(20)
declare cur_score cursor
for select sname,cname,final
from student a join score b on a.studentno=b.studentno join course c on b.courseno=c.courseno
open cur_score
fetch next from cur_score into @sname,@cname,@final
while @@fetch_status=0
begin
print @sname+@cname+@final
fetch next from cur_score into @sname,@cname,@final
end
close cur_score
deallocate cur_score
2)本地游标cur_score_update,计算学生期末成绩的等级,并更新level列
declare @usually numeric(6, 2),@final numeric(6, 2), @level nchar(11)
declare cur_score_update cursor
for select final,usually,level from score
open cur_score_update
fetch next from cur_score_update into @final,@usually, @level
while @@fetch_status=0
begin
select @final, @usually, @level
if(@final * 0.9 + @usually * 0.1 >= 90)
update score set level='优秀'
where current of cur_score_update
else if(@final * 0.9 + @usually * 0.1 >= 80)
update score set level='良好'
where current of cur_score_update
else if(@final * 0.9 + @usually * 0.1 >= 70)
update score set level='中等'
where current of cur_score_update
else if(@final * 0.9 + @usually * 0.1 >= 60)
update score set level='及格'
where current of cur_score_update
else
update score set level='不及格'
where current of cur_score_update
fetch next from cur_score_update into @final,@usually, @level
end
close cur_score_update
deallocate cur_score_update
3)全局游标cur_stunum_update,检查修改每个开课号在选课表中的学生选修人数
declare @courseno nchar(11), @stunumber tinyint, @total tinyint
declare cur_stunum_update cursor
for select courseno,period from course
open cur_stunum_update
fetch next from cur_stunum_update into @courseno,@stunumber
while @@fetch_status=0
begin
select @courseno,@stunumber
--定义内层游标
declare stu_cursor cursor
for
select count(studentno) as 'total'
from score
where score.courseno = @courseno
group by courseno
open stu_cursor
fetch next from stu_cursor into @total
while @@fetch_status=0
begin
if @total > @stunumber print '这个开课计划选择的人数已经超过限选人数,请调整!'
if @total < @stunumber
update course set period=@total
where current of cur_stunum_update
fetch next from stu_cursor into @total
end
close stu_cursor
deallocate stu_cursor
--内层游标结束
fetch next from cur_stunum_update into @courseno,@stunumber
end
close cur_stunum_update
deallocate cur_stunum_update
4)全局游标cur_credit_check,检查学生获得的学分数是否正确,如果不正确,则进行修改
declare @总评 numeric(6, 2),@credit numeric(6, 2)
declare cur_credit_check cursor
for select 总评, credit from student_corse2
open cur_credit_check
fetch next from cur_credit_check into @总评, @credit
while @@fetch_status=0
begin
select @总评, @credit
if(@总评 < 60)
update student_corse2 set credit=0
where current of cur_credit_check
fetch next from cur_credit_check into @总评, @credit
end
close cur_credit_check
deallocate cur_credit_check
(7)在学生表增加一个字段“预警级别”,然后编写游标对每个学生已修课程成绩进行检测,统计累计所欠学分,达到20分的学生,修改“预警级别”为“学业警示”,达到30分的学生,修改“预警级别”为“编入下一年级”。
declare @累计学分 numeric(6, 2),@预警级别 nchar(11)
declare score_cursor cursor
for select 累计学分,预警级别 from student
open score_cursor
fetch next from score_cursor into @累计学分,@预警级别
while @@fetch_status=0
begin
select @累计学分,@预警级别
if(@累计学分>=20)
update student set 预警级别='学业警示'
where current of score_cursor
if(@累计学分>=30)
update student set 预警级别='编入下一年级'
where current of score_cursor
fetch next from score_cursor into @累计学分,@预警级别
end
close score_cursor
deallocate score_cursor
实验8.1 创建索引
实验八-1 创建索引
假设在teaching数据库应用中存在如下查询语句,请根据实际需要为该数据库表创建索引。
score(studentno,courseno,usually,finally) student(studentno,sname,sex,birthday,classno,point,phone,Email)
teach_class(teacherno,classno,courseno)
设置索引时,根据字段的实际读写频率设置其填充因子。
if exists(select name from sysindexes where name = 'IDX_sc')
drop index student.sc
go
create index IDX_sc on student(studentno, classno)
–在score表的studentno和courseno列上建立一个复合索引sc_index
create index sc_index on score(studentno,courseno)
–在teach_class表的teacherno和courseno列上建立一个复合索引tc_index
create index tc_index on teach_class(teacherno,courseno)
(1)查询选修课程且期末成绩不为空的学生人数。
select (select COUNT(final) from score )
(2)查询所有Email使用126邮箱的学生的学号、姓名和电子邮箱地址。
select studentno,sname,email
from student
where email like'%@126%'
(3)查询每名学生的学号、选修课程数目、总成绩,并将查询结果存放到生成的“学生选课统计表”中。
select studentno,SUM(final) as 总成绩,COUNT(*) as 选课门数 into 学生选课统计表中
from score
group by studentno
select * from 学生选课统计表中
(4)查询选修’c05109’课程,并且期末成绩在前5名的学生学号、课程号和期末成绩。
select top 5 studentno,courseno,final
from score
where courseno='c05109'
order by final desc
(5)查询教授两门及以上课程的教师编号、课程编号和任课班级。
select teacherno,classno,courseno
from teach_class
group by teacherno
having COUNT(courseno)>=2
(4)查询课程编号以’c05’开头,被三名及以上学生选修,且期末成绩的平均分高于75分的课程号、选修人数和期末成绩平均分,并按平均分的降序排序。
select courseno,COUNT(studentno) as 选修人数,AVG(final) as 平均分
from score
where courseno like'c05%'
group by courseno
having COUNT(*)>=3
(7)查询所有17级学生的期末成绩平均分,要求利用COMPUTE BY方法显示每一名学生的学生编号、课程号、期末成绩的明细表,以及期末成绩平均分的汇总表。
select studentno 学生编号,courseno 课程号,final 期末成绩, avg(final) 平均分
from score
where studentno like '%17'
compute avg(final)
实验8.2 视图的建立
实验八-2 视图的建立
1.创建一个视图v_avgstu,查询每个学生的学号、姓名及平均分,并且按照平均分降序排序。
create view v_avgstu
as select top(100) percent student.studentno, student.sname, avg(score.final) average
from student, score
where student.studentno = score.studentno and score.final is not null
group by student.studentno, student.sname
order by avg(score.final) desc
go
select * from v_avgstu
2.修改v_teacher的视图定义,添加WITH CHECK OPTION选项。
alter view v_teacher
as select *
from teacher
with check option
3.通过视图v_teacher向基本表teacher中分别插入数据(‘05039’, ‘张馨月’, ‘计算机应用’, ‘讲师’, ‘计算机学院’)和(‘06018’, ‘李诚’, ‘机械制造’, ‘副教授’, ‘机械学院’),并查看插入数据情况。
insert into v_teacher values('05039','张馨月','计算机应用','讲师','计算机学院')
insert into v_teacher values('06018','李诚','机械制造','副教授','机械学院')
go
select * from v_teacher
select * from teacher
4.通过视图v_teacher将基本表teacher中教师编号为’05039’的教师职称修改为’副教授’
update v_teacher
set prof = '副教授'
where teacherno = '05039'
go
select * from teacher
5.建立试图v_score,查询每名学生的学号、性别和年龄,并在年龄字段上建立非聚集索引index_age
create index index_age on student(birthday)
go
create view v_score
as
select studentno, sex, birthday
from student
go
实验9.1 存储过程
实验九-1存储过程
(1)创建一个名称为StuInfo的存储过程,要求完成以下功能:在student表中查询17级学生的学号、姓名、性别、出生日期和电话个字段的内容
if exists (select name from sysobjects
where name='StuInfo'and type='p')
drop procedure StuInfo
go
create procedure StuInfo
as
select studentno,sname,sex,birthday,phone
from student
where substring(studentno,1,2)='17'
(2) 创建一个存储过程ScoreInfo,完成的功能是在表student、表course和表score中查询以下字段:学号、姓名、性别、课程名称、期末分数。
if exists(select name from sysobjects
where name='ScoreInfo'and type='p')
drop procedure ScoreInfo
go
create procedure ScoreInfo
as
select student.studentno,student.sname,student.sex,course.cname,score.final from student,course,score
where student.studentno=score.studentno and score.courseno=course.courseno
go
(3)创建一个名称为Student_Info1的存储过程,要求查询某位同学指定课程的成绩和学分。该存储过程接受与传递参数精确匹配的值。
if exists(select name from sysobjects
where name='Student_Info1'and type='p')
drop procedure Student_Info
go
create procedure Student_Info
@course nchar(8)
as
select course.period,credit from course
where course.cname=@course
(4)利用Transact-SQL语句创建一个带有参数的存储过程ProcInsert,向score表插入一条由参数指定的选课记录(学号、课程号、平时成绩、期末成绩),并查询该学生的姓名、选修的所有课程名称、平时成绩和期末成绩。
if exists(select name from sysobjects
where name='ProcInset'and type='p')
drop procedure ProcInset
go
create procedure ProcInset(
@studentno nchar(11),
@courseno nchar(6),
@usully numeric(6,2),
@final numeric(6,2))
as
insert into score values(@studentno,@courseno,@usully,@final)
select sname,cname,usually,final
from student,score,course
where student.studentno = score.studentno and student.studentno = @studentno and score.courseno= course.courseno
(5)统计输入课程的成绩分布情况,即按照各分数段来统计人数;
Rank( division CHAR(20), number INT )
division:‘[0,60)’ , ‘[60,80)’, ‘[80,100]’
CREATE TABLE Rank(
division char(20),
sub_sum int
)
INSERT INTO Rank(division)
VALUES('[0,60)'),('[60,70)'),('[70,80)'),('[80,90)'),('[90,100]');
CREATE PROCEDURE printcourse @pcname char(20)
AS
DECLARE @pcno char(20),@pcount int
UPDATE Course SET Cname=@pcname WHERE Cname=@pcname
IF(@@ROWCOUNT=0)
BEGIN
RAISERROR('您输入的课程号不存在,请重新输入!', 16, 1)
RETURN
END
SELECT @pcount=COUNT(*) FROM score WHERE final<60
UPDATE Rank SET sub_sum=@pcount WHERE division='[0,60)'
SELECT @pcount=COUNT(*) FROM score WHERE final>=60 AND final<70
UPDATE Rank SET sub_sum=@pcount WHERE division='[60,70)'
SELECT @pcount=COUNT(*) FROM score WHERE final>=70 AND final<80
UPDATE Rank SET sub_sum=@pcount WHERE division='[70,80)'
SELECT @pcount=COUNT(*) FROM score WHERE final>=80 AND final<90
UPDATE Rank SET sub_sum=@pcount WHERE division='[80,90)'
SELECT @pcount=COUNT(*) FROM score WHERE final>=90 AND final<=100
UPDATE Rank SET sub_sum=@pcount WHERE division='[90,100]'
EXEC printcourse '数据库'
SELECT * FROM Rank
实验9.2 触发器
实验九-2 触发器
(1)创建AFTER触发器:在score表上创建一个插入、更新类型的触发器TR_ScoreCheck,当在score字段中插入或修改考试分数后,触发该触发器,检查分数是否在0-100之间。
if exists(select name from sysobjects where name = 'TR_ScoreCheck' and type = 'TR')
drop trigger TR_ScoreCheck
go
create trigger TR_ScoreCheck on score
for insert, update
as
if update(final) print 'AFTER触发器开始执行……'
begin
declare @score real
select @score = (select final from inserted)
if @score >= 100 or @score < 0
print '输入的分数有误,请确认输入的考试分数!'
end
go
(2)创建INSTEAD OF触发器:在course表上创建一个删除类型的触发器TR_NotAllowDelete,当在course表中删除记录时,触发该触发器,显示不允许删除表中数据的提示信息。
if exists(select name from sysobjects where name = 'TR_NotAllowDelete' and type = 'TR')
drop trigger TR_NotAllowDelete
go
create trigger TR_NotAllowDelete on course
after delete
as
print '本表中的数据不允许被删除'
rollback
go
(3)为student表创建一个名为“tri_de_s”的后触发器,当删除某条记录时,自动检查表score中是否有该学生的选课记录,如果存在则取消删除操作。
if exists(select name from sysobjects where name = 'tri_de_s' and type = 'TR')
drop trigger tri_de_s
go
create trigger tri_de_s on student
for delete
as
begin
declare @sno char(10)
select @sno = deleted.studentno from deleted
if exists(select studentno from score where studentno = @sno)
begin
print 'score存在记录,禁止删除'
rollback tran
end
end
(4)为teacher 表创建触发器,保证教授工资不能低于4000元。
teacher(eno, job,sal)
if exists(select name from sysobjects where name = 'TR_SalCheck' and type = 'TR')
drop trigger TR_SalCheck
go
create trigger TR_SalCheck on teacher
for insert,update
as
begin
declare @s numeric
select @s = (select sal from inserted)
if(@s < 4000)
begin
print '教授工资不能低于4000元'
rollback
end
end
实验9.3 存储过程附加
实验10 事务定义
事物定义
(1)定义一个事务Insert_XXXXX(用学号命名),在teaching数据库的student表和score表中新增一名学生的基本信息记录和选课记录,并提交该事务。通过查询语句验证插入语句是否成功。
(2)定义一个事务Insert_score,在teaching数据库向score表中增加学号为’16122221326’学生的选课记录,并回滚该事务。通过查询语句验证插入语句是否成功。
(3)定义一个事务,将student表中学号为’16122221326’的学生性别修改为’女’,并设置一个保存点,然后将score表中学号为’16122221326’的学生期末成绩修改,最后回滚到事务的保存点,提交事务。通过查询语句验证修改语句是否成功。
(4)下面程序使用嵌套事务完成对score表的操作,在查询编辑器中输入如下程序并执行,并对执行过程和执行结果进行分析和解释。
USE teaching
GO
BEGIN TRAN outer_trans
BEGIN TRAN inner_trans
SELECT * FROM score WHERE studentno = '16122221326';
UPDATE score
SET final=95
WHERE studentno = '16122221326';
SELECT * FROM score WHERE studentno = '16122221326';
COMMIT TRAN inner_trans;
UPDATE score
SET usually=90
WHERE studentno = '16122221326';
SELECT * FROM score WHERE studentno = '16122221326';
ROLLBACK TRAN outer_trans;
SELECT * FROM score WHERE studentno = '16122221326';
如果提交外部事务,也将提交内部嵌套事务,如果回滚外部事物,也将回滚所有内部事务。
实验11 锁
实验十一 锁
- 设置隔离级别为read committed(缺省)方式,体会两个事务的并发执行结果。
(1) 打开第一个查询窗口,新建一个事务T1,更新student表的数据,如下:
begin transaction T1
update student set classno='1010' where studentno='16122221326'
(2) 打开第二个查询窗口,新建一个事务T2,查询student表的数据,如下:
begin transaction T2
select * from student
(3)观察发生的现象,查询语句可以执行吗,是否可以读到没有提交的事务?
不能执行事务T2中的查询语句
(4)在第一个查询窗口中,提交事务T1,然后观察查询语句是否执行了吗?
能执行事务T2中的查询语句,并且读取到了T1提交的事务
(5)加锁和解锁的操作是数据库用户吗?
不是,操作的是事务
(6) 在第二个查询窗口中,提交事务T2
- 设置隔离级别为read committed(缺省)方式,体会两个事务的并发执行结果。
(1) 打开第一个查询窗口,新建一个事务T1,查询student表的数据,如下:
begin transaction T1
select * from student
(2) 打开第二个查询窗口,新建一个事务T2,更新student表的数据,如下:
begin transaction T2
update student set classno='1010' where studentno='16122221326'
commit transaction T2
(3)观察发生的现象,更新语句可以执行吗,是否可以修改正在被其他事务读取的数据?
可以
(4)在第一个查询窗口中,再次执行查询语句select * from student,是否可以重复读?
(5) 在第一个查询窗口中,提交事务T1
- 设置隔离级别为read uncommitted方式,体会两个事务的并发执行结果。
(1) 打开第一个查询窗口,新建一个事务T1,更新student表的数据,如下:
begin transaction T1
update student set classno='1010' where studentno='16122221326'
(2) 打开第二个查询窗口,新建一个事务T2,查询student表的数据,如下:
begin transaction T2
select * from student
(3)观察发生的现象,查询语句可以执行吗,是否可以读到没有提交的事务?
可以执行查询语句,但是不能读取到没有提交的事务
(4)在第一个查询窗口中,回滚事务T1,T2事务的查询发生了什么问题?
没有出现问题
(5) 在第二个查询窗口中,提交事务T2
- 设置隔离级别为read committed(缺省)方式,体会两个事务的并发执行结果。
(1) 打开第一个查询窗口,新建一个事务T1,更新student表的数据,如下:
begin transaction T1
update student set classno='1010' where studentno='16122221326'
(2) 打开第二个查询窗口,新建一个事务T2,更新score表的数据,如下:
begin transaction T2
update score set usual=usual+10
(3) 在第一个查询窗口,执行语句
update score set final=final+5
观察发生的现象,语句update score set final=final+5可以执行吗?
不可以执行
(4) 在第二个查询窗口中,执行语句
update student set point=point+1
观察发生的现象,语句update student set point=point+1可以执行吗?
可以执行文章来源:https://www.toymoban.com/news/detail-427743.html
(5)在成功执行的窗口输入commit语句并执行文章来源地址https://www.toymoban.com/news/detail-427743.html
实验13 SQL server安全管理
到了这里,关于数据库应用与开发【实验题汇总】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!