从存储过程返回错误结果?

False results being returned from stored procedure?

我在 Microsoft SQL 服务器中编写了一个存储过程,应该 从 4Matrix 导入结果并将它们插入 Results table 在我的门户网站上。它确实会导入结果,但是,其中一些不正确。

这是存储过程的代码 ImportResults:

USE [MyPortal]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:      CURRICULUM\r.richards
-- Create date: 24/10/2017
-- Description: Imports Selected Subject Results From 4Matrix into MyPortal
-- =============================================
ALTER PROCEDURE [dbo].[ImportResults]
    @SubjectID int,
    @ResultSet varchar(50)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @StudentID int
    DECLARE @Upper int = (SELECT COUNT(*) FROM Students)
    DECLARE @ResultSetID int
    DECLARE @ResultValue NVARCHAR(50)
    DECLARE @Pointer int = 1

    WHILE @Pointer <= @Upper
    BEGIN
        SET @StudentID = (SELECT studentID 
                          FROM 
                              (SELECT
                                   ROW_NUMBER() OVER (ORDER BY Students.studentLastName) AS rownumber,
                                   studentID
                               FROM 
                                   Students) AS foo
                          WHERE rownumber = @Pointer)
        SET @ResultSetID = (SELECT rsID 
                            FROM ResultSets 
                            WHERE (rsName = @ResultSet))

        EXEC Get4MResult @StudentID, @SubjectID, @ResultSet, @Result = @ResultValue OUTPUT

        INSERT INTO Results(resultSet, resultStudent, resultSubject, resultValue)
        VALUES(@ResultSetID, @StudentID, @SubjectID, @ResultValue)

        SET @Pointer = @Pointer + 1
    END
END

过程 'Get4MResult' 的代码部分如下(如果是 这个 过程导致了问题):

USE [MyPortal]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:      CURRICULUM\r.richards
-- Create date: 24/10/2017
-- Description: Obtains Selected Result from 4Matrix Interface
-- =============================================
ALTER PROCEDURE [dbo].[Get4MResult]
    @StudentID int,
    @SubjectID int,
    @ResultSet varchar(50),
    @Result nvarchar(50) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @KeyStage INT
    DECLARE @4MPupilID INT
    DECLARE @4MSubjectID INT
    DECLARE @4MSeriesID INT

    DECLARE @YearGroup VARCHAR(50) = (SELECT MyPortal.dbo.Students.studentYear 
                                      FROM MyPortal.dbo.Students 
                                      WHERE(Students.studentID = @StudentID))

    IF(@YearGroup = 'Year 10' OR @YearGroup = 'Year 11')
        SET @KeyStage = 4
    ELSE 
        SET @KeyStage = 3

    SET @4MPupilID = (SELECT FOUR.dbo.Pupils.PupilID 
                      FROM FOUR.dbo.Pupils 
                      WHERE MIS = @StudentID)

    IF(@KeyStage = 4)
        SET @4MSubjectID = (SELECT MyPortal.dbo.Subjects.subjectQsiKs4 
                            FROM MyPortal.dbo.Subjects 
                            WHERE (MyPortal.dbo.Subjects.subjectID = @SubjectID))
    ELSE 
        SET @4MSubjectID = (SELECT MyPortal.dbo.Subjects.subjectQsiKs3 
                            FROM MyPortal.dbo.Subjects  
                            WHERE (MyPortal.dbo.Subjects.subjectID = @SubjectID))

    SET @4MSeriesID = (SELECT FOUR.dbo.Series.SeriesID 
                       FROM FOUR.dbo.Series 
                       WHERE (SeriesName = @YearGroup+' - '+@ResultSet))

    SELECT @Result = Result 
    FROM FOUR.dbo.Results 
    WHERE (PupilID = @4MPupilID 
      AND SubjectID = @4MSubjectID 
      AND SeriesID = @4MSeriesID)
END

理论上,只有 ID 为 4M 的学生(来自学生 Table)应该有结果。只有 KS3 和 KS4 学生有 4Matrix ID,所以当我 运行 它时,应该只有大约 400 个结果被输入结果 table。

当我 运行 脚本 ImportResults 1,'Spring 2017' 时,它 确实 导入如下结果:

但是,有 1080 个结果条目,而不是我预期的 ~400 个结果。它们不是重复的,但我发现有些学生的结果不存在,我不确定脚本哪里出错导致了这个。看这里:

这名学生 (4292) 在这门学科中应该有 'A*'。但是,经过进一步检查,我发现该学生不在 KS3 或 KS4,因此没有 4Matrix ID。所以我不确定 'A*' 是从哪里来的。

本应为该学生导入结果。

我已经检查了两部分的代码,但看不出错误在哪里?

我成功解决了问题:

问题似乎出在最初的 ImportResults 过程中,即使学生 没有 有 4Matrix ID,他们仍然是以 ID 0 或 NULL 传递,返回 A* 值。

我更正了程序如下:

DECLARE @StudentID int
DECLARE @Upper int = (SELECT COUNT(*) FROM Students)
DECLARE @ResultSetID int
DECLARE @ResultValue NVARCHAR(50)
DECLARE @Pointer int = 1
DECLARE @4MatrixID int
WHILE @Pointer <= @Upper
  BEGIN
    SET @StudentID =(SELECT studentID FROM (
                                             SELECT
                                               ROW_NUMBER() OVER (ORDER BY 
Students.studentLastName) AS rownumber,
                                               studentID
                                             FROM Students
                                           ) AS foo
    WHERE rownumber = @Pointer)
    SET @4MatrixID = (SELECT student4mID FROM Students WHERE(studentID = 
@StudentID))


    IF(@4MatrixID IS NULL) <===== ###'ADDED THIS TO ELIMINATE STUDENTS WITHOUT IDs'###



      GOTO nextStudent <===== ###'SENDS TO THE END OF THE SCRIPT' [1]###




    SET @ResultSetID = (SELECT rsID FROM ResultSets WHERE(rsName = 
@ResultSet))
    EXEC Get4MResult @StudentID,@SubjectID,@ResultSet,@Result = @ResultValue 
OUTPUT
INSERT INTO Results(resultSet, resultStudent, resultSubject, resultValue)
  VALUES(@ResultSetID,@StudentID,@SubjectID,@ResultValue)




    nextStudent: <===[1]= ###'GETS PUSHED HERE AND THEREFORE BYPASSES THE RESULT RETRIEVAL'###
    SET @Pointer = @Pointer + 1
  END

这意味着必须使用可怕的 GOTO 语句,但它现在可以正常工作了! :)