2013-10-12 51 views
0

我是MySQL新手,並且遇到輕微問題。最後一行內部光標獲取兩次

我有一個存儲過程有2個遊標,一個在另一個裏面。

問題是內部遊標的最後一行總是被提取兩次。每當最後一行進入內部遊標時,就會發生這種情況,每次迭代外部遊標。

下面是完整的存儲過程:

CREATE PROCEDURE MAP_TITLES_TO_SRC_CATEGORIES() 
BEGIN 
    Block1:BEGIN 
     DECLARE matched_titles_category_id INTEGER DEFAULT 0; 
     DECLARE tmp_genre_category_id INTEGER DEFAULT 0; 
     DECLARE index_wanted INT Default 0; 
     DECLARE genre_string VARCHAR(255); 
     SET matched_titles_category_id = (SELECT category_id FROM oc_category_description WHERE name='matched_titles' LIMIT 1); 
     Block2:BEGIN 
      DECLARE src_cursor_finished INTEGER DEFAULT 0; 
      DECLARE src_cursor_src_code_value varchar(9) DEFAULT ""; 
      DECLARE src_cursor_genres_value varchar(100) DEFAULT ""; 
      DECLARE src_cursor CURSOR FOR SELECT it.src_id, it.Genres FROM src_table it order by it.Title asc; 
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET src_cursor_finished = 1; 
      OPEN src_cursor; 
       REPEAT 
        FETCH src_cursor INTO src_cursor_src_code_value, src_cursor_genres_value; 
        INSERT INTO src_log (log_entry) VALUES (CONCAT('Cursor #1 populated with :: src_cursor_src_code_value: ',src_cursor_src_code_value,' & src_cursor_genres_value: ',src_cursor_genres_value)); 
        Block3:BEGIN 
         DECLARE products_cursor_finished INTEGER DEFAULT 0; 
         DECLARE products_cursor_id_value INTEGER DEFAULT 0; 
         DECLARE products_cursor_isbn_value varchar(9) DEFAULT ""; 
         DECLARE products_cursor CURSOR FOR SELECT prod.product_id, prod.isbn FROM oc_product prod where prod.isbn !='' and prod.sku='1'; 
         DECLARE CONTINUE HANDLER FOR NOT FOUND SET products_cursor_finished = 1; 
         OPEN products_cursor; 
          REPEAT 
           FETCH products_cursor INTO products_cursor_id_value, products_cursor_isbn_value; 
           INSERT INTO src_log (log_entry) VALUES (CONCAT('Cursor #2 populated with :: products_cursor_id_value: ',products_cursor_id_value,' & products_cursor_isbn_value: ',products_cursor_isbn_value)); 
           SET index_wanted = 0; 
           IF products_cursor_isbn_value = src_cursor_src_code_value THEN 
            INSERT INTO src_log (log_entry) VALUES (CONCAT('match entry for prod ',products_cursor_id_value,' in match cat id ',matched_titles_category_id,' BEGIN')); 
            INSERT INTO oc_product_to_category VALUES (products_cursor_id_value, matched_titles_category_id); 
            INSERT INTO src_log (log_entry) VALUES (CONCAT('match entry for prod ',products_cursor_id_value,' in match cat id ',matched_titles_category_id,' END')); 
            genres_loop:LOOP 
             SET index_wanted=index_wanted+1; 
             SET genre_string=SPLIT_STR(src_cursor_genres_value,',',index_wanted); 
             IF genre_string='' THEN 
              LEAVE genres_loop; 
             END IF; 
             SET tmp_genre_category_id = (SELECT category_id FROM oc_category_description WHERE name = genre_string LIMIT 1); 
             INSERT INTO src_log (log_entry) VALUES (CONCAT('genre entry for prod ',products_cursor_id_value,' and genre cat ID ',tmp_genre_category_id,' BEGIN')); 
             INSERT INTO oc_product_to_category VALUES (products_cursor_id_value, tmp_genre_category_id); 
             INSERT INTO src_log (log_entry) VALUES (CONCAT('genre entry for prod ',products_cursor_id_value,' and genre cat ID ',tmp_genre_category_id,' END')); 
            END LOOP genres_loop; 
           END IF; 
          Until products_cursor_finished END REPEAT; 
         CLOSE products_cursor; 
        END Block3; 
       UNTIL src_cursor_finished END REPEAT; 
      CLOSE src_cursor; 
     END Block2; 
    END Block1; 
END; 

正如你所看到的,我每次登錄後FETCH接收到的數據,我看不透這一點,結果表明我觀察到的問題。

有關該錯誤的任何想法?

回答

1

測試src_cursor_finished必須在FETCH命令後立即完成。
但代碼試圖從遊標讀取,然後執行許多操作(不檢查是否取成功),然後在UNTIL聲明結束檢查條件:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET src_cursor_finished = 1; 
OPEN src_cursor; 
    REPEAT 
    FETCH products_cursor INTO products_cursor_id_value, products_cursor_isbn_value; 

    -- The condition must be tested HERE: 
    -- IF products_cursor_finished <> 1 THEN do something 
    --  or even better: 
    -- IF products_cursor_finished = 1 THEN LEAVE; 

    ................ 
    .............. 
    .......... 
    ............ 
    ................... 
    Until products_cursor_finished END REPEAT; 
+0

如果我使用'IF products_cursor_finished = 1那麼離開;',在'離開'之後,我沒有提及任何事情嗎?我的意思是,離開什麼? – Ahmad

+0

我最終將'REPEAT'替換爲'LOOP'循環。示例:www.mysqltutorial.org/mysql-cursor/ – Ahmad

+0

LEAVE存在最新的LOOP,請參閱此鏈接:http://dev.mysql.com/doc/refman/5.0/en/leave.html – krokodilko