【SQL Server数据库】Transact-SQL语句实验(五)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41427568/article/details/102750283

本文上接【SQL Server数据库】建库、建表、简单查询语句(一),本系列主要记录数据库实验内容,本文主要记录T-SQL语句实验。
具体表的属性attribute和名称table name也可以在上面链接中找到。

T-SQL

T-SQL 即 Transact-SQL,是 SQL 在 Microsoft SQL Server 上的增强版,它是用来让应用程序与 SQL Server 沟通的主要语言。T-SQL 提供标准 SQL 的 DDL (数据定义语言Data Definition Language)和 DML (数据操纵语言Data Manipulation Language)功能,加上延伸的函数、系统预存程序以及程式设计结构(例如 IF 和 WHILE)让程式设计更有弹性。具体T-SQL语法的讲解可以参考这篇文章:
T-SQL 基础简介

实验内容

/*定义一个实型变量,并将其值输出*/
declare @num float
set @num=111.231
print @num
print cast(@num as varchar(12))
print cast(@num as int)

/*定义一个字符变量,并将其处理后输出*/
declare @a varchar(20)
set @a='test'
select ('compute' + @a) as '计算结果'

/*根据授课班号自定义变量,查询符合要求的学生成绩*/
declare @cno varchar(6), @grade float
set @cno='218801'
set @grade=90
select *
from sc
where CNO=@cno and GRADE=@grade

/*BEGIN……END……的使用*/
begin
	declare @val float
	set @val=111.111
	begin
		print '变量@val的之为:'
		print cast(@val as char(12))
	end
end

/*利用 CASE 查看学生的成绩等级*/
select SNO,CNO,
case
	when grade>=80 then 'A'
	when grade>=70 then 'B'
	when grade>=60 then 'C'
	else 'D'
	end
as 等级
from sc
go

/*创建一个视图,统计每个学生的学习情况。若其平均成绩超过 90,则其学习情况为优
秀;若其平均成绩在 80 和 90 之间,则其学习情况为优秀良好;依次类推。*/
create view student_grade
as 
(select sc.SNO,SNAME,AVG(GRADE) as avg_grade,
case
when AVG(grade)>90 then '优秀'
when AVG(grade)>80 then '良好'
when AVG(grade)>70 then '中等'
when AVG(grade)>60 then '合格'
else '不合格'
end
as 学习情况
from sc,student
where student.SNO=sc.SNO
group by sc.SNO,SNAME
)
go

/*利用 WHILE 结构,求:1+2+3+..+100 的值*/
declare @i int,@j int
set @i=0
set @j=1
while @j<=100
	begin
	set @i=@i+@j
	set @j=@j+1
	end
print '1+2+3+...+100='+cast(@i as varchar(4))

/*利用 IF…ELSE,查询课程号为'234901'的学生的总平均成绩,如果大于 90,输出优秀,
在 80-90 之间,输出优良,其它输出一般*/
declare @grade int
select @grade=AVG(grade) from sc where CNO='234901'
if @grade>90
	print('优秀')
else
	begin
	if @grade>80
		print('优良')
	else
		print('一般')
	end

/*或者使用case when then这样*/
select CNO,AVG(GRADE) as 平均成绩,
case
when AVG(GRADE)>10 then '优秀' 
when AVG(GRADE)>10 then '优良'
when AVG(GRADE)>10 then '一般'
end
as 等级
from sc
where CNO='234901'
group by CNO

go
/*定义一函数,实现如下功能,对于一给定的学号 studentSNO,查询该值在 student 中
是否存在,存在返回 1,不存在返回 0。*/
create function check_id(@studentSNO char(8))  --定义函数名与变量
returns integer  --规定返回值类型
as 
begin
		declare @num int
		if (exists(select * from student where SNO=@studentSNO))
			set @num=1
		else
			set @num=0
		return @num
end	
go

--调用函数
select dbo.check_id('20000073') 是否存在这个学号 ;
go

/*使用下面的 SQL 语句调用第 9 题的函数。要求:当向表 student 中插入一条记录时,
首先调用函数 check_id,检查该记录的学号在表 student 中是否存在,不存在,才可以插
入。*/
declare @flag int
set @flag=dbo.check_id('2810125')
if @flag=0
begin
	insert into student
	values('2810125','陈旭','200','男','0001','1999-10-02','4117')
	print('插入学生信息成功')
end
else
	print('这个学生的信息已经在表中了')


select *
from student
where SNO='2810125'

/*求学生选课的门数,列出其姓名及选课门数*/
select distinct SNAME,(select COUNT(*) from sc where SNO=student.SNO) as 选课信息
from student

/*或者如下*/
select SNAME
from student left outer join sc on student.SNO=sc.SNO
group by SNAME 

/*根据课程号动态查询学生的选课人数*/
declare @cno char(8)
declare @sql varchar(200)
set @cno='218801'
--使用字符串连接动态生成SQL语句
set @sql='select count(*) from sc where cno='''+@cno+'''' --在字符串中使用转义字符''表示单引号'
exec(@sql)
set @cno='203402'
--使用字符串连接动态生成SQL语句
set @sql='select count(*) from sc where cno='''+@cno+''''
exec(@sql)
go

/*用游标结合循环,输出全校各种姓氏及其人数*/
--记录游标中的行数
declare @count int
--循环变量
declare @i int
--各种姓氏和人数
declare @xingshi varchar(6),@num int
--定义游标
declare @name_cursor CURSOR
--给游标赋值
set @name_cursor = CURSOR  for 
					   select distinct SUBSTRING(SNAME,1,1) as xingshi,COUNT(*) as num
					   from student
					   group by SUBSTRING(SNAME,1,1)
--循环变量初始化
set @i=0
--打开游标
open @name_cursor
--@@CURSOR_ROWS表示游标对应的记录集中记录的个数
set @count=@@CURSOR_ROWS
print '游标中的行数为:'+cast(@count as varchar(8))
--判断游标中是否有记录
if @count<=0 --没有记录
	begin
		print '游标中没有记录'
	end
--存在记录
else 
	begin
		--循环处理每一条记录
		while(@i<@count)
			begin
			fetch next from @name_cursor into @xingshi,@num
			print convert(varchar(20),@i)+' '+@xingshi+' '+cast(@num as char(20))
			set @i=@i+1
			end
	close @name_cursor
	end
go

/*利用游标结合循环,统计学院各种姓氏的人数*/
--定义游标
declare @count int
declare @i int
declare @xing varchar(6)
declare @rs int
declare @sql varchar(8000)
set @i=0
set @sql=''
declare @name_cursor cursor
set @name_cursor=cursor for
				 (select SUBSTRING(SNAME,1,1) as xing,COUNT(*) as rs
				  from student
				  group by substring(SNAME,1,1))
open @name_cursor
set @count=@@CURSOR_ROWS
if @count<0
	begin
		print('没有记录')
	end
else
	begin
		while(@i<@count-300)
			begin
				fetch next from @name_cursor into @xing,@rs
				set @sql=@sql+'(select count(*) from student where DNO=a.DNO and substring(sname,1,1)='''+@xing+''') as '+@xing+','
				set @i=@i+1
			end
			--动态生成第301个sql语句
			fetch next from @name_cursor into @xing,@rs
			set @sql=@sql+'(select count(*) from student where DNO=a.DNO and substring(sname,1,1)='''+@xing+''') as '+@xing
			close @name_cursor
			print @sql
			set @sql='select DNAME,'+@sql+' from (select distinct student.DNO ,DNAME from student,dept where student.DNO=dept.DNO) as a'
			print @sql
			exec(@sql)
	end
				
go

select DNAME,(select COUNT(*) 
			  from student
			  where DNO=a.DNO and SUBSTRING(SNAME,1,1)='李') as '李'
from (select distinct student.DNO,DNAME 
	  from student,dept
	  where student.DNO=dept.DNO) as a

/*利用 CASE 实现学生表中学院编号到学院名称的映射*/
select SNO,SNAME,
case
when DNO='0001' then '机电工程学院'
when DNO='0002' then '计算机及信息工程学院'
when DNO='0003' then '商学院'
end
as 所属学院
from student
go

/*定义一函数,实现如下功能,对于一给定的学号 studentSNO 和课程号 studentCNO 查
询该值在 student 和 course 中是否存在,存在返回 1,不存在返回 0。*/
create function check_sc(@studentSNO char(8),@studentCNO char(8))
returns integer
as
	begin
	declare @flag int
	if(exists(select * from student where SNO=@studentSNO) and 
	exists(select * from course where CNO=@studentCNO))
	set @flag=1
	else
	set @flag=0
	return @flag
	end
go

/*使用该函数*/
declare @num int
set @num =dbo.check_sc('20000010','000101')
print @num
go

/*根据教师名自定义变量,查询符合要求的教师授课情况*/
declare @teacher_name char(6)
set @teacher_name='陈春'
select *
from course
where TNAME=@teacher_name

/*求授课班号及选修该授课班号的学生人数*/
select CNO ,(select COUNT(*) from sc where course.CNO=CNO ) as 学生人数
from course
go

/*定义一函数,根据学号返回学生的选课门数(参考 INSERT 触发器)*/
create function count_course(@student_sno char(8))
returns integer
as
begin
declare @count int
set @count=(select COUNT(*) from sc where SNO=@student_sno)
return @count 
end
go

/*使用函数*/
declare @num int
set @num=dbo.count_course('')
print convert(char(8),@num)
print cast(@num as char(8))

/*修改学生的成绩,若大于 80 分,增加 5 分,否则,增加 8 分*/
update sc
set GRADE=
(
case
when GRADE>=80 then GRADE+5
else GRADE+8
end
)

/*按课程名称,统计其平均分,列出其课程名称和平均分*/
select distinct CNAME,(select AVG(GRADE) from sc where CNO in (select CNO from course where c1.CNAME=course.CNAME)) as cno_avg
from course as c1

/*求每个学生选课的门数及其平均分,列出其姓名、课程门数及平均分*/
select SNAME,(select COUNT(*) from sc where student.SNO=sc.SNO) as 课程门数,(select AVG(GRADE) from sc where student.SNO=sc.SNO) as 平均分
from student
go

/* 定义一函数,依据学生的姓名,查询其所选课程的门数*/
create function count_course_from_sname(@SNAME varchar(8))
returns int
as 
begin
declare @count int
set @count=(select COUNT(CNO) from sc where SNO=(select SNO from student where SNAME=@SNAME))
return @count
end
go

/*使用该函数*/
declare @num int
set @num =dbo.count_course_from_sname('李好洋')
print(@num)

/*根据学院名称,统计学生人数,列出学院名称和学生人数*/
declare @dept_name varchar(20)
set @dept_name='计算机及信息工程学院'
select @dept_name as 学院名称,(select COUNT(*) from student where student.DNO=(select DNO from dept where dept.DNAME=@dept_name)) as 学院人数

/*若存在学号为‘20081200’的学生,则显示其姓名,否则,显示相应提示信息*/
if(exists(select * from student where SNO='20000010'))
begin
select SNAME from student where SNO='20000010'
end
else
begin
print '查无此人'
end

/*查找每个学生超过他选修课程平均成绩的课程相关信息,列出学号,课程号,成
绩,选课平均成绩*/
select sc.SNO,CNO,GRADE,avg_grade
from sc,
(select SNO,AVG(GRADE) as avg_grade
from sc
group by SNO) as a
where a.SNO=sc.SNO and GRADE>avg_grade
go

/*创建一视图,统计每门课程的学习情况。若课程平均成绩超过 90,则其学习情况
为优秀;若课程平均成绩在 80 和 90 之间,则其学习情况为优秀良好;依次类推。*/
create view grade_level
as select CNO,
   case
   when AVG(GRADE)>90 then '优秀'
   when AVG(GRADE) between 80 and 90 then '良好'
   end 
   as 评级
   from sc
   group by CNO
go

/*利用游标结合循环,统计各门课程的各种分数的人数。*/
declare @cursor cursor
declare @count int
declare @i int
declare @grade int 
declare @sql varchar(8000)
set @i=0
set @sql=''
set @cursor=cursor for
			(select distinct GRADE
			from sc
			)
open @cursor
set @count=@@CURSOR_ROWS
while @i<@count-1
begin
fetch next from @cursor into @grade
set @sql=@sql+' (select COUNT(*) from sc where a.CNO=CNO and GRADE='+cast(@grade as varchar(3))+') as '+''''+convert(varchar(3),@grade)+''''+','
set @i=@i+1
end

fetch next from @cursor into @grade
set @sql=@sql+' (select COUNT(*) from sc where a.CNO=CNO and GRADE='+cast(@grade as varchar(3))+') as '+''''+convert(varchar(3),@grade)+''''
close @cursor
set @sql='select a.CNAME,'+@sql+' from (select distinct sc.CNO,CNAME from sc,course where sc.CNO=course.CNO) as a'
print @sql
exec(@sql)

猜你喜欢

转载自blog.csdn.net/qq_41427568/article/details/102750283