Cursorfetch Error: Datatypes and number of variables match the select query

Cursorfetch Error: Datatypes and number of variables match the select query

当我从主程序调用此程序时遇到问题。错误:Cursorfetch:INTO 列表中声明的变量数必须与所选列的变量数相匹配。

ALTER PROCEDURE [ABC].[SKIPPED_EMAILS] (@BatchID INT, @Record VARCHAR(20), @SkippedReason VARCHAR(100), @RecordID INT, @TaskID INT, @TableID INT, @EmailCount INT OUTPUT) AS
BEGIN

    DECLARE @EmailBody      VARCHAR(4000)
    DECLARE @Subject        VARCHAR(30)
    DECLARE @PersonObj      INT
    DECLARE @PersonID       VARCHAR(10)
    DECLARE @PersonName     VARCHAR(40)
    DECLARE @EmailAddr      VARCHAR(50)
    DECLARE @PhoneNo        VARCHAR(20)
    DECLARE @EmailStatus    VARCHAR(1) = 'H'

    SET @Subject = 'Skipped Emails'
            
    SELECT @EmailBody = Text FROM FLT.EMAIL_TEMP WHERE InformationID = 'SKIPPED_EMAIL'
            
    SELECT @EmailBody = replace(replace(@EmailBody, '[Reason]', @SkippedReason), '[Record]', @Record);

    SET @EmailCount = 0;
    
    DECLARE EMAILREC CURSOR LOCAL FOR 
    SELECT person.PersonObj, person.PersonID, person.PersonName, person.EmailAddr, person.PhoneNo
    FROM [ABC].[PERSON] person
    LEFT JOIN [ABC].[School] school ON (person.PersonObj = school.StudentObj)
    LEFT JOIN [ABC].[Class] class ON (school.StudentObj = class.StudentObj)
    WHERE person.Status = 'A' 
      AND school.StudentType = 'STU'
      AND class.AttendeeID= 'ATTENDEE'
      AND class.Status = 'A'
      
    OPEN EMAILREC
    FETCH NEXT FROM EMAILREC INTO @PersonObj, @PersonID, @PersonName, @EmailAddr, @PhoneNo
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
        INSERT INTO FLT.LOG_EMAILOG VALUES(0, @BatchID, 0, @TaskID, @TableID, @RecordID, GETDATE(), 'MBX', @Subject, @EmailBody,NULL,'',1, 'PER',@PersonObj, @PersonID, @PersonName, @EmailAddr, @PhoneNo, 'N', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @EmailStatus);
            
        SET @EmailCount = @EmailCount + 1;
            
        FETCH NEXT FROM EMAILREC INTO @PersonObj, @PersonID, @PersonName, @EmailAddr, @PhoneNo
    
    END
    
    CLOSE EMAILREC
    DEALLOCATE EMAILREC
END
GO

我不知道 FLT.LOG_EMAILOG 的结构,但我建议您在插入语句中指定此 table 的列,如下所示:

INSERT INTO FLT.LOG_EMAILOG (f1,f2...,f30) VALUES(0, @BatchID, 0, @TaskID, @TableID, @RecordID, GETDATE(), 'MBX', @Subject, @EmailBody,NULL,'',1, 'PER',@PersonObj, @PersonID, @PersonName, @EmailAddr, @PhoneNo, 'N', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @EmailStatus);

这根本不需要是游标。只需使用 INSERT...SELECT...

SQL 中游标的第一条规则: 除非别无选择,否则不要使用它们。 SQL 喜欢基于集合的事物,将批处理作为一个命令执行,而不是 WHILE 循环和游标。

ALTER PROCEDURE [ABC].[SKIPPED_EMAILS]
    (@BatchID INT, @Record VARCHAR(20), @SkippedReason VARCHAR(100), @RecordID INT,
    @TaskID INT, @TableID INT, @EmailCount INT OUTPUT)
AS

DECLARE @EmailBody VARCHAR(4000);
SELECT @EmailBody = Text FROM FLT.EMAIL_TEMP WHERE InformationID = 'SKIPPED_EMAIL';
SET @EmailBody = replace(replace(@EmailBody, '[Reason]', @SkippedReason), '[Record]', @Record);

INSERT INTO FLT.LOG_EMAILOG
SELECT
    0, @BatchID, 0, @TaskID, @TableID, @RecordID, GETDATE(), 'MBX', 'Skipped Emails', @EmailBody,
    NULL,'',1, 'PER',p.PersonObj, p.PersonID, p.PersonName, p.EmailAddr, p.PhoneNo, 'N',
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'H'
FROM [ABC].[PERSON] person p
LEFT JOIN [ABC].[School] school ON (person.PersonObj = school.StudentObj)
LEFT JOIN [ABC].[Class] class ON (school.StudentObj = class.StudentObj)
WHERE person.Status = 'A' 
  AND school.StudentType = 'STU'
  AND class.AttendeeID= 'ATTENDEE'
  AND class.Status = 'A';

SET @EmailCount = @@ROWCOUNT;

GO

我强烈建议您声明要插入的确切列名。