【SQL Server】存储过程 练习题

本文提供了4道典型的题目

题目 + 答案 + 分析

-- 前排提示:下题中使用的表极其主键为  studentInfo(stuId), subjectInfo(subId), scoreInfo(stuId, subId)



-- Q1:该存储过程有两个输入参数(@specialty, @name),查询某系,某姓名的学生信息:包括学号、姓名、年龄、课程名、成绩
-- 注:要求在创建存储过程之前,判断该存储过程是否已创建,若已创建则先删除,并给出"已删除";否则给出"不存在,可创建"

-- 判断存储过程是否已经存在:
if exists(select name from sysobjects where name = 'fun1' and type = 'p')
begin
	drop procedure fun1,
	print '已删除'
end 
else
	print '不存在,可创建'

-- 分析:经典的三表内联;再根据专业和姓名进行where筛选就可以了
-- 创建存储过程
create procedure fun1
	@specialty nvarchar(10),
	@stuName nvarchar(10)
as
begin
	select stuId, stuName, stuAge, subName, score
	from scoreInfo as sc
	inner join studentInfo as stu on sc.stuId = stu.stuId
	inner join subjectInfo as sub on sc.subId = sub.subId			-- 三表内连
	where stu.specialty = @specialty and stu.stuName = @stuName		-- where筛选
end

-- 调用测试
exec fun1 '计算机','Loli1'



-- Q2: 创建一个名为fun2的存储过程,可查询某门课程考试的平均成绩
-- 注:平均成绩可以输出;平均成绩假定类型为int

create proc fun2
	@subName nvarchar(10),		-- 作为输入
	@avg int output				-- 作为输出(将结果带出去)
as
begin
	set @avg =
	select AVG(score)
	from scoreInfo, subjectInfo
	where scoreInfo.subId = subjectInfo.subId and subName = @subName
end



-- Q3:创建一个名为fun3的存储过程。输入学号@stuId、课程名称@subName作为参数值,
--     将查询scoreInfo和subjectInfo表,并通过输出参数@score和@credit获取该学生该课程的成绩和学分。
--     如果分数大于等于60,则返回对应课程的学分,否则返回学分值0。

-- 分析:两表内连后,查询到成绩;再根据成绩给credit赋值(case语句,if语句都可以)
create procedure fun3
	@stdId int,						-- 输入参数
	@subName nvarchar(10),			-- 输入参数
	@score int output,				-- 输出参数
	@credit int output				-- 输出参数
as
begin
	select @score = sc.score, @credit = case when sc.score >= 60 then sub.credit else 0 end	
	from subjectInfo as sub, scoreInfo as sc												   
	where sub.subId = sc.subId and sc.stuId = @stuId and subName = @subName
end
-- 分析:select的第一句很长但逻辑清晰;select不仅和print一样可以输出,本身也和set一样有赋值的意味



-- Q4:创建一个名为fun4的存储过程:既有输入又有输出,给出课程名称,统计输出该课程的各分数段人数

-- 分析:直接分组+sum聚合,这个思路是行不通的。问题出在分组依据———此时我们需要按范围进行分组。
--      思路很巧妙:每统计一个范围的个数,就用case语句根据该范围将成绩转化为1和0,在进行sum(这样就统计出了每个范围的个数)

create procedure fun4
	@subName nvarchar(10)
as
begin
	select sc.subName as '课程名',
		   sum(case when score >= 90 then 1 else 0 end) as '[90+ 范围',
		   sum(case when score < 90 and score >= 80 then 1 else 0 end) as '[80, 90)范围',
		   sum(case when score < 80 and score >= 70 then 1 else 0 end) as '[70, 80)范围',
		   sum(case when score < 70 and score >= 60 then 1 else 0 end) as '[60, 70)范围',
		   sum(case when score < 60 then 1 else 0) as '(60-范围'
	from subjectInfo, scoreInfo
	where subjectInfo.subId = scoreInfo.subId and subName = @subName
	group by subName
end

猜你喜欢

转载自blog.csdn.net/m0_46202073/article/details/106782704
今日推荐