在另一个存储过程中调用存储过程

时间:2012-08-10 06:17:13

标签: sql-server stored-procedures

我有一个存储过程来获取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;

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

2 个答案:

答案 0 :(得分: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

你的存储过程没有用(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; 

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

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

答案 1 :(得分:0)

这可能对您有用

Use nested stored procedure results in calling stored procedure Sql Server 2008

你可以这样使用

IF .....
INSERT #Tbl (Fields)
EXEC usp_SelectProc1 @Arg1, Arg2...Argn
ELSE
INSERT #Tbl (Fields)
EXEC usp_SelectProc2 @Arg1, Arg2...Argn