1

我正在编写我的第一个程序并且出现错误。我已将错误减少到删除行,但不确定原因。有人可以在这里发现问题吗?是变量吗?

DROP PROCEDURE IF EXISTS MPT_PROC;
DELIMITER $$
CREATE PROCEDURE MPT_PROC
MODIFIES SQL DATA
BEGIN

    #-- DECLARE statements

    DECLARE v_user_id       INT DEFAULT 0;

    DECLARE no_more_rows    BOOLEAN;
    DECLARE v_loop_cntr     INT DEFAULT 0;
    DECLARE v_num_rows      INT DEFAULT 0;

    DECLARE c_userfiles CURSOR 
    FOR
        SELECT distinct f.user_id
        FROM MPT_STG_FILEUPLOAD f
        WHERE f.status = 'A';  #-- Accepted

        DECLARE CONTINUE HANDLER FOR NOT FOUND
        SET no_more_rows = TRUE;

        OPEN c_userfiles;

        #-- Loop through each user_id found as pending
        the_loop: LOOP

            FETCH c_userfiles INTO v_user_id;

            #-- Break out of the loop if
            #-- 1) there were no records, or
            #-- 2) we've processed them all.
            IF no_more_rows THEN
                CLOSE c_userfiles;
                LEAVE the_loop;
            END IF;

            DELETE FROM MPT_STG_FILEUPLOAD s
            WHERE s.user_id = v_user_id;

            COMMIT;  #--Commiting the changes for this user
        END LOOP the_loop;

    END IF;

END
DELIMITER ;
4

1 回答 1

1

MySQL 不允许您在 DELETE 语句中为要从中删除的表提供别名。

 DELETE FROM MPT_STG_FILEUPLOAD WHERE user_id = v_user_id;

并失去英镑符号作为注释分隔符。双破折号是标记注释开头的标准。看起来您END IF在程序即将结束时拥有无与伦比的优势。

DROP PROCEDURE IF EXISTS MPT_PROC;
DELIMITER $$
CREATE PROCEDURE MPT_PROC
MODIFIES SQL DATA
BEGIN
  DECLARE v_user_id       INT DEFAULT 0;
  DECLARE no_more_rows    BOOLEAN;
  DECLARE v_loop_cntr     INT DEFAULT 0;
  DECLARE v_num_rows      INT DEFAULT 0;

  DECLARE c_userfiles CURSOR 
  FOR
  SELECT distinct f.user_id
    FROM MPT_STG_FILEUPLOAD f
   WHERE f.status = 'A';  -- Accepted

  DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET no_more_rows = TRUE;

  OPEN c_userfiles;

  -- Loop through each user_id found as pending
  the_loop: LOOP

    FETCH c_userfiles INTO v_user_id;

    -- Break out of the loop if
    -- 1) there were no records, or
    -- 2) we've processed them all.
    IF no_more_rows THEN
      CLOSE c_userfiles;
      LEAVE the_loop;
    END IF;

    DELETE FROM MPT_STG_FILEUPLOAD s
     WHERE s.user_id = v_user_id;

    COMMIT;  --Commiting the changes for this user
  END LOOP the_loop;

END$$
DELIMITER ;

如果user_id不是该 MPT_STG_FILEUPLOAD 表上的主键,则您的过程可能正在删除未标记为“已接受”的行。如果 user_id 在该表中有两行,并且其中一行被标记为已接受,而另一行则不是,该怎么办。你想删除这两行吗?

看起来您声明了两个未在任何地方引用的变量,v_loop_cntr并且v_num_rows,如果不需要它们,我建议您将它们注释掉。

这整个过程可以在单个 SQL 语句中更有效地完成。

于 2012-07-06T22:07:24.173 回答