2012-08-10 270 views
2

我有一个存储过程按分数来获得一个疗程的GPA乘以信贷的结果:调用存储在另一个存储过程的过程

ALTER PROCEDURE dbo.GpaCreditFromScore 
(
    @score INT, 
    @credits INT, 
    @gpaCredit INT OUTPUT 
) 
AS 
IF (@score < 60) 
BEGIN 
    SET @gpaCredit = 0.0 
END 
ELSE IF (@score < 62) 
BEGIN 
    SET @gpaCredit = 1.0 * @credits 
END 
ELSE IF (@score < 65) 
BEGIN 
    SET @gpaCredit = 1.7 * @credits 
END 
ELSE IF (@score < 67) 
BEGIN 
    SET @gpaCredit = 2.0 * @credits 
END 
ELSE IF (@score < 70) 
BEGIN 
    SET @gpaCredit = 2.3 * @credits 
END 
ELSE IF (@score < 75) 
BEGIN 
    SET @gpaCredit = 2.7 * @credits 
END 
ELSE IF (@score < 80) 
BEGIN 
    SET @gpaCredit = 3.0 * @credits 
END 
ELSE IF (@score < 85) 
BEGIN 
    SET @gpaCredit = 3.3 * @credits 
END 
ELSE IF (@score < 90) 
BEGIN 
    SET @gpaCredit = 3.7 * @credits 
END 
ELSE IF (@score < 95) 
BEGIN 
    SET @gpaCredit = 4.0 * @credits 
END 
ELSE IF (@score <= 100) 
BEGIN 
    SET @gpaCredit = 4.3 * @credits 
END 

而另一个存储过程来计算所有学生的GPA乘信用:

ALTER PROCEDURE dbo.ComputeGpa 
AS 
    ;WITH x AS 
(
    SELECT StudentID, Score, rn = ROW_NUMBER() OVER 
    (PARTITION BY StudentID, CourseID 
    ORDER BY Semester DESC) 
    FROM dbo.UndergraduateScoreSet 
) 
SELECT StudentID, Gpa /* call dbo.GpaCreditFromScore here to get @gpaCredit */ 
FROM x 
WHERE rn = 1 
GROUP BY StudentID; 

由于逻辑非常复杂,我不知道如何实现这一点。请大家帮忙〜

+3

如果你有一个表列'LowerScoreBound','UpperScoreBound '和'乘数',你可以很容易地获得乘数作为一个基于集的操作。然后,你可以大大简化你的存储过程(这应该是一个UDF)或完全消除它。 – 2012-08-10 06:19:44

+0

与其编辑您的问题以包含答案,您应该将答案发布为...答案(然后请回滚您的编辑)。 – 2012-08-10 07:24:18

回答

2

不幸的是,因为proc dbo.GpaCreditFromScore接受并返回了标量参数,这意味着你必须通过遍历你的学生来计算所有分数,通过使用像游标一样的可怕东西。

由于@Damien提到,你应该改变dbo.GpaCreditFromScore是一个用户定义的函数,像这样:

CREATE FUNCTION dbo.GpaCreditFromScore 
(
    @score INT, 
    @credits INT 
) 
RETURNS INT 
AS 
    BEGIN 
     DECLARE @gpaCredit INT 
     IF (@score < 60) 
     BEGIN 
      SET @gpaCredit = 0.0 
     END 
     ELSE IF (@score < 62) 
     BEGIN 
      SET @gpaCredit = 1.0 * @credits 
     END 
     ELSE IF (@score < 65) 
     BEGIN 
      SET @gpaCredit = 1.7 * @credits 
     END 
     ELSE IF (@score < 67) 
     BEGIN 
      SET @gpaCredit = 2.0 * @credits 
     END 
     ELSE IF (@score < 70) 
     BEGIN 
      SET @gpaCredit = 2.3 * @credits 
     END 
     ELSE IF (@score < 75) 
     BEGIN 
      SET @gpaCredit = 2.7 * @credits 
     END 
     ELSE IF (@score < 80) 
     BEGIN 
      SET @gpaCredit = 3.0 * @credits 
     END 
     ELSE IF (@score < 85) 
     BEGIN 
      SET @gpaCredit = 3.3 * @credits 
     END 
     ELSE IF (@score < 90) 
     BEGIN 
      SET @gpaCredit = 3.7 * @credits 
     END 
     ELSE IF (@score < 95) 
     BEGIN 
      SET @gpaCredit = 4.0 * @credits 
     END 
     ELSE IF (@score <= 100) 
     BEGIN 
      SET @gpaCredit = 4.3 * @credits 
     END 
     RETURN @gpaCredit 
    END 

你的存储过程并不完全工作(?哪里学分来自),但这个想法是现在使用UDF你的CTE的领域,像这样:

ALTER PROCEDURE dbo.ComputeGpa 
AS 
    ;WITH x AS 
    (
     SELECT StudentID, Score, 9 AS Credits, rn = ROW_NUMBER() OVER 
     (PARTITION BY StudentID, CourseID 
     ORDER BY Semester DESC) 
     FROM dbo.UndergraduateScoreSet 
    ) 
    SELECT StudentID, dbo.GpaCreditFromScore(Score, Credits) AS GpaCredit 
    FROM x 
    WHERE rn = 1 
    GROUP BY StudentID; 

编辑 OP发现错误 - 因为GROUP BY的,我们需要一个总的,当然。谢谢!:

SELECT StudentID, SUM(dbo.GpaCreditFromScore(Score, Credits)) AS GpaCredit 
+1

正如我在问题的结尾提到的那样。但是你的回答真的很有帮助!非常感谢! – Ovilia 2012-08-10 07:21:39

相关问题