2014-03-25 27 views
0

我在使用mysql存儲過程中的遊標提取循環出現問題。我的存儲過程運行一個重新排序過程,它的工作狀況良好,直到訂單編號跳過單個數字的排序的最後一個記錄。例如,如果我有10條記錄並且排序過程從1開始,則應該在結果記錄中顯示從1到10的所有數字。但是,我的存儲過程跳過最後一個計數,在上面的例子中爲10,並重新編號最終記錄11,因此計數從9到11.無論涉及的記錄數量如何,情況都是如此。MySQL CURSOR循環在存儲過程中添加了額外的傳遞

程序的邏輯非常簡單:

我有持有產品類型的記錄,與使用常規的分批循環過程中重新排序基於使用記錄的排序順序列的表。

CREATE TABLE `PRODUCT_TYPE` (
    `PRODUCT_TYPE_ID` int(11) NOT NULL AUTO_INCREMENT, 
    `PRODUCT_TYPE_NAME` varchar(45) NOT NULL, 
    `PRODUCT_CATEGORY_ID` int(11) DEFAULT NULL, 
    `LIFESPAN_MONTHS` int(11) DEFAULT NULL, 
    `USER_ID` int(11) DEFAULT NULL, 
    `UPDATED_BY` int(11) DEFAULT NULL, 
    `UPDATED_DATE` datetime DEFAULT NULL, 
    `CREATED_DATE` datetime DEFAULT NULL, 
    `CREATED_BY` int(11) DEFAULT NULL, 
    `REVIEWED` bit(1) NOT NULL DEFAULT b'0', 
    `SORT_ORDER` int(11) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`PRODUCT_TYPE_ID`), 
    KEY `fk_PRODUCT_TYPE_PRODUCT_CATEGORY1_idx` (`PRODUCT_CATEGORY_ID`), 
    KEY `fk_PRODUCT_TYPE_USERS1_idx` (`USER_ID`), 
    KEY `fk_PRODUCT_TYPE_USERS2_idx` (`UPDATED_BY`), 
    KEY `fk_PRODUCT_TYPE_USERS3_idx` (`CREATED_BY`), 
    CONSTRAINT `fk_PRODUCT_TYPE_PRODUCT_CATEGORY1` FOREIGN KEY (`PRODUCT_CATEGORY_ID`) REFERENCES `PRODUCT_CATEGORY` (`PRODUCT_CATEGORY_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    CONSTRAINT `fk_PRODUCT_TYPE_USERS1` FOREIGN KEY (`USER_ID`) REFERENCES `USERS` (`USER_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    CONSTRAINT `fk_PRODUCT_TYPE_USERS2` FOREIGN KEY (`UPDATED_BY`) REFERENCES `USERS` (`USER_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    CONSTRAINT `fk_PRODUCT_TYPE_USERS3` FOREIGN KEY (`CREATED_BY`) REFERENCES `USERS` (`USER_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=latin1; 

我夜間的基礎上運行以下存儲過程基於使用SORT_ORDER列來記錄,以各類型引用的數目來重新排序所述產品類型的記錄。

DELIMITER $$ 

CREATE DEFINER=`root`@`localhost` PROCEDURE `REORDER_MANUFACTURERS`() 
BEGIN 

DECLARE DONE BOOL; 
DECLARE MID INT; 
DECLARE MNAME VARCHAR(255); 
DECLARE USES INT; 
DECLARE SORT_ORDER_COUNTER INT; 

DECLARE CUR CURSOR FOR SELECT M.MANUFACTURER_ID, M.MANUFACTURER_NAME, COUNT(U.UNIT_ID) AS USES 
FROM MANUFACTURERS M LEFT JOIN mydb.UNITS U ON M.MANUFACTURER_ID = U.MANUFACTURER_ID 
GROUP BY M.MANUFACTURER_ID, M.MANUFACTURER_NAME 
ORDER BY USES DESC, MANUFACTURER_NAME; 

DECLARE CONTINUE HANDLER FOR NOT FOUND SET DONE = TRUE; 

SET SORT_ORDER_COUNTER = 0; 

OPEN CUR; 

READ_LOOP: LOOP 

    FETCH CUR INTO MID, MNAME, USES; 

    UPDATE MANUFACTURERS SET SORT_ORDER = SORT_ORDER_COUNTER WHERE MANUFACTURER_ID = MID; 

    IF DONE THEN 
     LEAVE READ_LOOP; 
    END IF; 

    SET SORT_ORDER_COUNTER = SORT_ORDER_COUNTER + 1; 

END LOOP; 

CLOSE CUR; 

END 

對於我的生活,我找不到這個邏輯會導致計數跳過節拍的問題。任何幫助,將不勝感激。

回答

0

更改

FETCH CUR INTO MID, MNAME, USES; 

UPDATE MANUFACTURERS SET SORT_ORDER = SORT_ORDER_COUNTER 
    WHERE MANUFACTURER_ID = MID; 

IF DONE THEN 
    LEAVE READ_LOOP; 
END IF; 

FETCH CUR INTO MID, MNAME, USES; 

IF DONE THEN 
    LEAVE READ_LOOP; 
END IF; 

UPDATE MANUFACTURERS SET SORT_ORDER = SORT_ORDER_COUNTER 
    WHERE MANUFACTURER_ID = MID; 

這是因爲:

如果你獲取了過去的最後一行的結果集,目標字段或變量的值ables是不確定的,並且NOTFOUND屬性返回TRUE

參考:(這是在Oracle遊標,但適用於其他人也):