1

製品テーブルの注文フィールドを更新するストアド プロシージャに取り組んでいました。ループ内の最後の項目 (cur) が 1 回ではなく 2 回増加する (ダブリングされる) という問題のみが機能します。そのようです:

+-----------------+
|商品 + 注文 |
|_id | | |
| | | | | |
| | 1 | 0 |
| | 2 | 1 |
| | など。など..|
| | 36 | 35 |
| | 37 | 36 |
| | 38 | 38 |
| | | |
+-----------------+

理由がわかりません。この場合のリンク テーブル (CategoryProduct) は、category_id が 2 の 38 になります。CALL curorder(2);

ストアド プロシージャ:

DELIMITER //
CREATE PROCEDURE curorder(
    IN catid INT
)
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE i INT DEFAULT 0;
    DECLARE p INT;
    DECLARE cur CURSOR FOR SELECT product_id FROM test.CategoryProduct WHERE category_id = catid;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN cur;
        read_loop: LOOP
            FETCH cur INTO p;
            UPDATE  `test`.`Product` SET  `order` =  i WHERE  `Product`.`product_id` =p;
            SET i = i + 1;
            IF done THEN
                LEAVE read_loop;
            END IF;
        END LOOP;
    CLOSE cur;
END //
DELIMITER ;

データベースはMysqlデータベースです。手順を改善するための提案はいつでも大歓迎です。

前もって感謝します。

編集:

SET i ステートメントを IF ステートメントの下に配置しようとしましたが、結果はありませんでした。

4

1 に答える 1

1

あなたは置くべきです:

IF done THEN
  LEAVE read_loop;
END IF;

update ステートメントの上で、最後に mysql がループを通過すると、新しい「p」がないため、古い変数が使用されます。しかし、私はインクリメントされます。

ストアド プロシージャをデバッグする良い方法は、ログ テーブルを使用することです。

CREATE TABLE procedureLog
(
  id INTEGER AUTO_INCREMENT,
  description TEXT,
  PRIMARY KEY (id)
);

この場合、次のクエリを使用して更新パラメーターをログに記録できます。

INSERT INTO  `test`.`procedureLog` (`id` ,`description`) VALUES (null,  CONCAT('id: ', CAST(p as CHAR), ' order: ', CAST(i as CHAR)));

幸運を!

于 2013-04-05T13:27:33.090 に答える