Execute stored procedure in OUTER APPLY block

2019-08-07 10:02发布

Why I can not use a stored procedure in OUTER APPLY block? I need to get int value from the stored procedure dbo.GetTeacherId and use this in WHERE clause. Here my code:

USE [StudentsDb]

DECLARE @teacherIdOut int;

SELECT   StudentLastName, StudentFirstName, StudentMiddleName, LessonName, Score, TLastName, TFirstName, TMiddleName
FROM     Scores
JOIN Students
ON Scores.StudentId=Students.StudentId
JOIN Lessons
ON Scores.LessonId=Lessons.LessonId
OUTER APPLY
(
    EXECUTE dbo.GetTeacherId 0, 0, @teacherId=@teacherIdOut -- here I get error
    SELECT Teachers.TeacherLastName, Teachers.TeacherFirstName, Teachers.TeacherMiddleName
    FROM Teachers
    WHERE Teachers.TeacherId=@teacherIdOut
)T(TLastName, TFirstName, TMiddleName)
WHERE Score <=3

And is there any other way to get the value from the stored procedure? Here my stored procedure dbo.GetTeacherId:

USE [StudentsDb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetTeacherId] @lessonId int, @groupId int, @teacherId int OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SELECT @teacherId=GroupTeachers.TeacherId
    FROM GroupTeachers
    WHERE GroupTeachers.LessonId=@lessonId AND GroupTeachers.GroupId=@groupId
END

1条回答
太酷不给撩
2楼-- · 2019-08-07 10:35

Stored procedure is not designed for that kind of usage, as it can perform operations other then selecting data, it can work without returning data or it can return different set in different scenarios.

Unlike stored procedures, functions are exactly suited to be used inline with other queries.

You have two options:

A) Create a scalar function that will return only a TeacherID and use it in your WHERE

CREATE FUNCTION udfGetTeacherID
(
    @lessonId int, @groupId int
)
RETURNS int
AS
BEGIN

    DECLARE @teacherId INT;

    SELECT @teacherId = GroupTeachers.TeacherId
    FROM GroupTeachers
    WHERE GroupTeachers.LessonId=@lessonId AND GroupTeachers.GroupId=@groupId;


    RETURN @teacherId;

END
GO

B) Create table-valued function that can get you all the data needed and you can just join (apply) on it.

CREATE FUNCTION udfGetTeacherName
(
    @lessonId int, @groupId int
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT t.TeacherLastName, t.TeacherFirstName, t.TeacherMiddleName
    FROM Teachers t
    INNER JOIN GroupTeachers g ON  T.TeacherID = g.TeacherID
    WHERE g.LessonId=@lessonId AND g.GroupId=@groupId
)
GO

Here is some reading: Difference between Stored Procedure and Function in SQL Server

查看更多
登录 后发表回答