使用游标写一个求每个学生成绩的平均值

时间:2021-04-25 00:45:03
使用游标写一个求每个学生成绩的平均值(sc,course,student)
 这是我写的,但是没有输出结果
use sstudent
declare @sno nvarchar(20),
        @cno int,
        @avg float
declare cursor_s cursor fast_forward
for 
  select cno,grade from sc where sno=@sno
open cursor_s 
fetch next from cursor_s into @cno,@sno
set @cno=cno
set @avg=(select avg(grade) from sc where cno=@cno )
print @avg
while(@@fetch_status=0)
begin
fetch next from cursor_s into @cno,@sno
set @avg=(select avg(grade) from sc where cno=@cno )
print @avg
end
close cursor_s
deallocate cursor_s
郁闷,我还想把它写成一个存储过程的,想不到这样哦就不行了

9 个解决方案

#1



不是这样就可以吗??

SELECT CNO, AVG(GRADE)
FROM SC
GROUP BY CNO

#2


set @cno=cno 


???

#3


@sno都没有赋值就打开游标了?

这个问题没有必要写游标吧

#4



直接AVG不就好了, 为什么游标呢?

-- =============================================
-- Author:      T.O.P
-- Create date: 2009/11/24
-- Version:     SQL SERVER 2005
-- =============================================
declare @TB1 table([cno] varchar(3),[course] varchar(4),[grade] int,[student] varchar(4))
insert @TB1
select '001','语文',99,'张三' union all
select '001','数学',2,'张三' union all
select '001','英语',14,'张三' union all
select '002','语文',43,'李四' union all
select '002','数学',2,'李四' union all
select '002','英语',56,'李四' union all
select '003','语文',2,'王五' union all
select '003','数学',43,'王五' union all
select '003','英语',99,'王五'

select [cno], [student], AVG([grade]) AS 平均成绩
from @TB1
group by [cno], [student]
order by cno


--测试结果:
/*
cno  student 平均成绩
---- ------- -----------
001  张三      38
002  李四      33
003  王五      48

(3 row(s) affected)

*/

#5


恩,确实不用游标很简单,但是,我想用游标和事件处理结合起来写一个存储过程,因为我想编写一个存储过程,运行时同时计算各门课的平均成绩和计算每个同学的平均成绩,而且将不及格的数据存储到一个临时表里输出。  我现在卡在第一步了。 (还想问问,游标他的具体应用到底是什么来的,很多时候不是可以不用游标么,那什么时候用的最多)

#6


那要看看你的具体需求..

#7


use student
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
alter PROCEDURE Procedure_newavg1
-- Add the parameters for the stored procedure here
@sno varchar(10),
@newavg float output
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare @cno int,
@grade int,
@avg float  

    -- Insert statements for procedure here
declare cursor_s cursor fast_forward
    for select cno,grade from sc where sno=@sno
open cursor_s
fetch next from cursor_s into @cno, @grade
while(@@fetch_status=0)
begin
set @avg=(select avg(grade) from sc where cno=@cno )
if(@grade<@avg)
begin
begin transaction
update sc
set grade=@avg
where sno=@sno and cno=@cno
if(@@error<>0)
begin
rollback tran
end
else
begin
commit tran
end
end

fetch next from cursor_s into @cno, @grade
end
set @newavg=(select avg(grade) from sc where sno=@sno)
close cursor_s
deallocate cursor_s
END
GO
这里有个示例代码,并没有给@sno赋值啊,加我觉得@sno=sno不本身就是在赋值么

#8


大家来讨论下嘛,存储过程,触发器,函数他们的作用,联系和用法,注意事项,真想可以找到一个总结,里面有很多很多例子的那种,现在的书代码都超少的,文字就特多,可惜没能力,可以做做项目就好了(要做项目又一堆的需求分析,和制作E-R图,特别是分解范式时,超麻烦啊,我现在手上没练习,感觉学的不够啊)

#9


引用 7 楼 houshen13828468384 的回复:
use student
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
alter PROCEDURE Procedure_newavg1
-- Add the parameters for the stored procedure here
@sno varchar(10),
@newavg float output
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare @cno int,
@grade int,
@avg float 

    -- Insert statements for procedure here
declare cursor_s cursor fast_forward
    for select cno,grade from sc where sno=@sno
open cursor_s
fetch next from cursor_s into @cno, @grade
while(@@fetch_status=0)
begin
set @avg=(select avg(grade) from sc where cno=@cno )
if(@grade <@avg)
begin
begin transaction
update sc
set grade=@avg
where sno=@sno and cno=@cno
if(@@error <>0)
begin
rollback tran
end
else
begin
commit tran
end
end

fetch next from cursor_s into @cno, @grade
end
set @newavg=(select avg(grade) from sc where sno=@sno)
close cursor_s
deallocate cursor_s
END
GO
这里有个示例代码,并没有给@sno赋值啊,加我觉得@sno=sno不本身就是在赋值么


这个实例代码是没有错的,因为@sno是作为存储过程的输入参数,不需要赋值,但是你1楼贴出来那段代码里面@sno不是输入参数,定义了以后就没有赋值,而你的游标又是打开select cno,grade from sc where sno=@sno 
这个记录集,当@sno没有赋值的时候这个查询返回的是空集,所以当然不会执行游标里面的代码

#1



不是这样就可以吗??

SELECT CNO, AVG(GRADE)
FROM SC
GROUP BY CNO

#2


set @cno=cno 


???

#3


@sno都没有赋值就打开游标了?

这个问题没有必要写游标吧

#4



直接AVG不就好了, 为什么游标呢?

-- =============================================
-- Author:      T.O.P
-- Create date: 2009/11/24
-- Version:     SQL SERVER 2005
-- =============================================
declare @TB1 table([cno] varchar(3),[course] varchar(4),[grade] int,[student] varchar(4))
insert @TB1
select '001','语文',99,'张三' union all
select '001','数学',2,'张三' union all
select '001','英语',14,'张三' union all
select '002','语文',43,'李四' union all
select '002','数学',2,'李四' union all
select '002','英语',56,'李四' union all
select '003','语文',2,'王五' union all
select '003','数学',43,'王五' union all
select '003','英语',99,'王五'

select [cno], [student], AVG([grade]) AS 平均成绩
from @TB1
group by [cno], [student]
order by cno


--测试结果:
/*
cno  student 平均成绩
---- ------- -----------
001  张三      38
002  李四      33
003  王五      48

(3 row(s) affected)

*/

#5


恩,确实不用游标很简单,但是,我想用游标和事件处理结合起来写一个存储过程,因为我想编写一个存储过程,运行时同时计算各门课的平均成绩和计算每个同学的平均成绩,而且将不及格的数据存储到一个临时表里输出。  我现在卡在第一步了。 (还想问问,游标他的具体应用到底是什么来的,很多时候不是可以不用游标么,那什么时候用的最多)

#6


那要看看你的具体需求..

#7


use student
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
alter PROCEDURE Procedure_newavg1
-- Add the parameters for the stored procedure here
@sno varchar(10),
@newavg float output
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare @cno int,
@grade int,
@avg float  

    -- Insert statements for procedure here
declare cursor_s cursor fast_forward
    for select cno,grade from sc where sno=@sno
open cursor_s
fetch next from cursor_s into @cno, @grade
while(@@fetch_status=0)
begin
set @avg=(select avg(grade) from sc where cno=@cno )
if(@grade<@avg)
begin
begin transaction
update sc
set grade=@avg
where sno=@sno and cno=@cno
if(@@error<>0)
begin
rollback tran
end
else
begin
commit tran
end
end

fetch next from cursor_s into @cno, @grade
end
set @newavg=(select avg(grade) from sc where sno=@sno)
close cursor_s
deallocate cursor_s
END
GO
这里有个示例代码,并没有给@sno赋值啊,加我觉得@sno=sno不本身就是在赋值么

#8


大家来讨论下嘛,存储过程,触发器,函数他们的作用,联系和用法,注意事项,真想可以找到一个总结,里面有很多很多例子的那种,现在的书代码都超少的,文字就特多,可惜没能力,可以做做项目就好了(要做项目又一堆的需求分析,和制作E-R图,特别是分解范式时,超麻烦啊,我现在手上没练习,感觉学的不够啊)

#9


引用 7 楼 houshen13828468384 的回复:
use student
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
alter PROCEDURE Procedure_newavg1
-- Add the parameters for the stored procedure here
@sno varchar(10),
@newavg float output
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare @cno int,
@grade int,
@avg float 

    -- Insert statements for procedure here
declare cursor_s cursor fast_forward
    for select cno,grade from sc where sno=@sno
open cursor_s
fetch next from cursor_s into @cno, @grade
while(@@fetch_status=0)
begin
set @avg=(select avg(grade) from sc where cno=@cno )
if(@grade <@avg)
begin
begin transaction
update sc
set grade=@avg
where sno=@sno and cno=@cno
if(@@error <>0)
begin
rollback tran
end
else
begin
commit tran
end
end

fetch next from cursor_s into @cno, @grade
end
set @newavg=(select avg(grade) from sc where sno=@sno)
close cursor_s
deallocate cursor_s
END
GO
这里有个示例代码,并没有给@sno赋值啊,加我觉得@sno=sno不本身就是在赋值么


这个实例代码是没有错的,因为@sno是作为存储过程的输入参数,不需要赋值,但是你1楼贴出来那段代码里面@sno不是输入参数,定义了以后就没有赋值,而你的游标又是打开select cno,grade from sc where sno=@sno 
这个记录集,当@sno没有赋值的时候这个查询返回的是空集,所以当然不会执行游标里面的代码