CREATE TABLE #TempTable (stuID int, courseID int,outputvalue decimal(9,5))
DECLARE @parm1 int, @parm2 int, @parm3 int, @parm4 int, @parm5 varchar(10)
, @parm6 datetime, @parm7 datetime, @parm8 datetime, @parm9 varchar(5),@parm10 char(1),@parm11 char(1)
DECLARE gradeCursor CURSOR FAST_FORWARD FOR
SELECT
3968585,
reg.building,
schd_ms.[section_key],
schd_ms_session.course_session,
CONVERT(nvarchar,reg.student_id),
'2012-07-01',
'2013-06-30',
REPLACE(convert(varchar, getdate(), 102),'.','-'),
'%',
'N',
'Y'
FROM test.dbo.reg
INNER JOIN schd_stu_course on schd_stu_course.student_id = reg.student_id
INNER JOIN schd_ms on schd_stu_course.section_key = schd_ms.section_key
JOIN schd_ms_session on schd_ms_session.section_key = schd_ms.section_key
where schd_ms.school_year = '2013'
OPEN gradeCursor
FETCH NEXT FROM gradeCursor INTO
@parm1,@parm2,@parm3,@parm4,@parm5,@parm6,@parm7,@parm8,@parm9,@parm10,@parm11
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @odecStudentAverage decimal(9,5)
EXECUTE [Test_Live].[dbo].[spi_GBCalcStudentAverage] @Parm1, @Parm2, @Parm3, @Parm4, @Parm5, @Parm6, @Parm7, @Parm8, @Parm9,@Parm10, @Parm11, @odecStudentAverage output
INSERT INTO #TempTable (stuID, courseID,outputvalue)
Select @Parm5, @Parm3, @odecStudentAverage
FETCH NEXT FROM gradeCursor INTO
@parm1,@parm2,@parm3,@parm4,@parm5,@parm6,@parm7,@parm8,@parm9,@parm10,@parm11
END
CLOSE gradeCursor
DEALLOCATE gradeCursor
SELECT
reg.student_id,
reg.building,
schd_ms.[course],
schd_ms.[section_key],
schd_ms.[description],
'',
'',
schd_ms_session.CREDIT,
schd_ms_session.START_PERIOD,
schd_ms_session.END_PERIOD,
schd_ms_session.ROOM_ID,
schd_ms_session.PRIMARY_STAFF_ID,
schd_ms_session.course_session,
#TempTable .outputvalue
FROM test_live.dbo.reg
INNER JOIN schd_stu_course on schd_stu_course.student_id = reg.student_id
INNER JOIN schd_ms on schd_stu_course.section_key = schd_ms.section_key
JOIN schd_ms_session on schd_ms_session.section_key = schd_ms.section_key
JOIN #TempTable on reg.student_id = #TempTable .stuID AND schd_ms.[section_key] = #TempTable .courseID
where schd_ms.school_year = '2013'
答案 0 :(得分:1)
这里最好的办法是将spi_GBCalcStudentAverage
程序更改为表值UDF,如果可以的话。这将允许您将其包含在一个基于集合的查询中,该查询将替换您的光标。
除非你这样做,否则你将无法摆脱光标,因为你无法在基于集合的查询中调用存储过程。
答案 1 :(得分:0)
如果你必须运行一个无法按行更改的存储过程,那么你就是SOL。你被光标困住了。
根据您填充的行数,您可能需要考虑将临时表#TempTable
更改为表变量@TempTable
。这可以提高性能,但是有一个阈值表大小,性能突然变为表变量。
答案 2 :(得分:0)
您要么获得正确重构所需的权利,要么以糟糕的表现为生,并告诉客户为何无法改善性能。
您可以通过两种方式进行重构:
重写sp以接受一组数据作为输入,通过可变的逗号分隔列表或通过使用tableinput变量(较新版本的SQl服务器)
或者创建一个tablevalued函数。如果他们可以给你sp的代码,你可以创建表值函数来使用set theroy而不是row-by-agonizing-row调用proc。他们更愿意让你创建一个新对象,而不是改变应用程序的其他部分正在使用的对象。
然而,所有这一切的真正关键在于,如果没有创建或更改需要更改的内容以解决问题所需的权限,那么期望您创建解决方案是绝对不可接受的。客户做了什么让你瘫痪。就好像你想让机械师修理你的车一样,但你拒绝给他启动发动机的钥匙。在给你车钥匙之前,你不能完成专业工作。