2

私は MySQL が初めてで、少し問題があります。

私は 2 つのカーソルを持つストアド プロシージャを持っています。

問題は、内部カーソルの最後の行が常に 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。この結果は、私が観察した問題を示しています。

バグに関するアイデアはありますか?

4

1 に答える 1

2

src_cursor_finishedFETCH コマンドの直後にテストを実行する必要があります。
しかし、コードはカーソルからフェッチしようとし、(フェッチが成功したかどうかをチェックせずに) 多くの操作を実行し、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;
于 2013-10-12T22:18:05.883 に答える