从存储过程返回错误结果?
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 语句,但它现在可以正常工作了! :)
我在 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 语句,但它现在可以正常工作了! :)