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;

由于逻辑相当复杂,我不知道如何实现这一点。请帮忙~

4

2 回答 2

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

您的 Stored Proc 不太有效(Credits 从何而来?),但现在的想法是在您的 CTE 字段上使用 UDF,如下所示:

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; 

EDIT OP 发现了一个错误——当然,由于 GROUP BY,我们需要一个聚合。谢谢!:

    SELECT StudentID, SUM(dbo.GpaCreditFromScore(Score, Credits)) AS GpaCredit
于 2012-08-10T06:24:01.527 回答
0

这可能对你有用

使用嵌套存储过程导致调用存储过程Sql Server 2008

你可以这样使用

IF .....
INSERT #Tbl (Fields)
EXEC usp_SelectProc1 @Arg1, Arg2...Argn
ELSE
INSERT #Tbl (Fields)
EXEC usp_SelectProc2 @Arg1, Arg2...Argn
于 2012-08-10T06:51:20.657 回答