【问题标题】:Cursorfetch Error: Datatypes and number of variables match the select queryCursorfetch 错误:数据类型和变量数与选择查询匹配
【发布时间】:2021-06-04 01:29:46
【问题描述】:

当我从我的主程序调用此程序时,我遇到了问题。错误: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

【问题讨论】:

  • 你到底为什么在这里使用游标,这整个代码可能是一个插入语句
  • @Charlieface 有一堆收件人,需要为 EMAIL 表中的每个收件人进行条目
  • 好的,那你为什么不能在一个 insert...select... 中做到这一点?
  • @Charlieface 你能帮我理解一下吗?我是 sql 新手
  • 就选择和分配的列而言,您的游标语句都是“平衡的”。您将需要进一步调试。也许错误出在您的主要程序中。坦率地说,如果您不需要游标,请不要使用它们 - 正如已经建议的那样。高级任何东西都应该使用和教授最佳实践。上船。

标签: sql-server tsql stored-procedures cursor


【解决方案1】:

这根本不需要是光标。只需使用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

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

【讨论】:

    【解决方案2】:

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

    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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多