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'
3 に答える
ここでの最善の策はspi_GBCalcStudentAverage
、可能であれば、プロシージャをテーブル値のUDFに変更することです。これにより、カーソルを置き換えるセットベースのクエリに含めることができます。
そうしないと、セットベースのクエリでストアドプロシージャを呼び出すことができないため、カーソルを取り除くことができません。
行ごとに変更できないストアドプロシージャを実行する必要がある場合は、ほとんどSOLです。あなたはカーソルで立ち往生しています。
詰め込む行数によっては、一時テーブル#TempTable
をテーブル変数に変更することを検討することをお勧めします@TempTable
。これによりパフォーマンスを向上させることができますが、パフォーマンスがテーブル変数で突然低下するしきい値テーブルサイズがあります。
リファクタリングに必要な権利を取得するか、パフォーマンスの低下に耐えて、パフォーマンスを改善できない理由をクライアントに伝える必要があります。
2つの方法でリファクタリングできます。
spを書き直して、コンマ区切りリストを使用した変数またはtableinput変数(新しいバージョンのSQlサーバー)を使用して、データのセットを入力として受け入れるようにします。
または、テーブル値関数を作成します。それらがspにコードを提供できる場合は、procの行ごとの呼び出しの代わりにsettheroyを使用するテーブル値関数を作成できます。彼らは、アプリケーションの他の部分が使用しているオブジェクトを変更するよりも、新しいオブジェクトを作成できるようにすることをいとわないかもしれません。
ただし、これらすべての本当の鍵は、問題を修正するために変更する必要があるものを作成または変更するために必要な権利なしにソリューションを作成することを期待することは決して受け入れられないということです。クライアントがしたことはあなたを不自由にします。まるで整備士に車の修理を依頼したかのようですが、エンジンを始動するための鍵を整備士に渡すことを拒否します。車のキーが渡されるまで、プロの作品を制作することはできません。