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
我强烈建议您声明要插入的确切列名。
当我从主程序调用此程序时遇到问题。错误: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
我强烈建议您声明要插入的确切列名。