2013-04-16 43 views
0

Iam与以下MySql存储过程有问题,当我尝试从控制台和应用程序运行它时,它给出一个SQLException,说光标未打开,有人可以告诉我为什么它不开放?mysql光标未打开

DELIMITER $$ 
DROP PROCEDURE IF EXISTS DELETE_EXPIRED_GIFTS_SP$$ 
CREATE PROCEDURE DELETE_EXPIRED_GIFTS_SP() 
    BEGIN 
    DECLARE gift_id_val INT; 
    DECLARE item_id_val INT; 
    DECLARE expiry_date DATETIME; 
    DECLARE no_more_gifts INT DEFAULT 0; 
    DECLARE num_rows INT DEFAULT 0; 
    DECLARE gift_items_cur CURSOR FOR 
     SELECT user_gift_id, item_id 
     FROM user_gift 
     WHERE status in (1,3); 

    DECLARE CONTINUE HANDLER FOR NOT FOUND 
    SET no_more_gifts = 1; 

    OPEN gift_items_cur; 
     select FOUND_ROWS() into num_rows; 
     the_loop: LOOP 
      FETCH gift_items_cur INTO gift_id_val, item_id_val; 

      IF no_more_gifts=1 THEN 
        CLOSE gift_items_cur; 
        LEAVE the_loop; 
      END IF; 

      SELECT end_time INTO expiry_date FROM item WHERE item_id = item_id_val; 

      IF expiry_date IS NOT NULL AND expiry_date <= UTC_TIMESTAMP() 
       THEN UPDATE user_gift SET status = 5 WHERE user_gift_id = gift_id_val; 
      END IF; 

     END LOOP the_loop; 
    CLOSE gift_items_cur; 
    END$$ 
DELIMITER ; 

和错误IAM越来越这里,

09:05:31,328 INFO [STDOUT] FATAL: com.abc.gift.support.impl.GiftSupportImpl - ERROR: CallableSt 
atementCallback; uncategorized SQLException for SQL [{call DELETE_EXPIRED_GIFTS_SP()}]; SQL state [2 
4000]; error code [1326]; Cursor is not open; nested exception is java.sql.SQLException: Cursor is n 
ot open 
+0

**请后确切的错误信息,而不是意译** –

+0

HI,更新了错误消息 – bluelabel

回答

1
the_loop: LOOP 
    : 
    IF no_more_gifts=1 THEN 
     CLOSE gift_items_cur;  <<< Number 1 
     LEAVE the_loop; 
    END IF; 
    : 
END LOOP the_loop; 
CLOSE gift_items_cur;    <<< Number 2 

在我看来,你关闭游标两次这里。

在处理程序激活并且no_more_gifts设置为1后第一次关闭它。此时您也退出循环,然后再次尝试关闭光标

我建议改变你的内在if声明只是:

IF no_more_gifts=1 THEN 
    LEAVE the_loop; 
END IF; 
+0

问题嗨,我不是MYSQL存储过程的专家,我在很多谷歌搜索的例子中看到这个验证已经包含在内。这使我认为这是游标相关存储过程的必须要求。我会删除它并让你知道结果。 – bluelabel

+0

@bluelabel,如果你使用的标签是最外面块(存储过程)的标签,那么是的,你需要关闭游标,因为你基本上已经退出了整个过程。但是,这里用于'leave'的标签是_loop,_的标签,所以它会在'end loop'行后继续运行,因此尝试第二次关闭光标。 – paxdiablo

+0

是的,我明白了你的观点,并猜测发生了什么变化。非常感谢您的帮助。 – bluelabel