如何处理我的存储过程循环中缺少的行?

时间:2019-07-04 17:48:08

标签: mysql stored-procedures

我有以下过程可循环访问article值,获取tag1并将其插入article_tag表中:

DELIMITER $$
CREATE PROCEDURE dt1()
BEGIN
    DECLARE maxid INT;
    DECLARE x INT;
    DECLARE t VARCHAR(30);
    DECLARE ntag1 int;
    SET maxid = (SELECT MAX(id) FROM `article`);
    SET x = (SELECT MIN(id) FROM  `article`) ;
    WHILE x<= maxid DO 
        SET t = (SELECT tag1 from `article` WHERE id=x);   
        SET ntag1 = (SELECT count(*) from `article_tag` WHERE tag=t);

        IF ntag1 = 0 
        THEN 
            INSERT INTO `article_tag` (tag, slug, frequency) VALUES (t, t, 1);
        ELSE 
            UPDATE  `article_tag` SET frequency = frequency + 1 WHERE tag=t;
        END IF;
        SET  x = x + 1; 
    END WHILE;
END$$

当while循环中有行id时,但是当它们之间缺少一些id时(例如works fine),此here 我得到

Query Error: Error: ER_BAD_NULL_ERROR: Column 'tag' cannot be null

我想知道处理这种缺失行的惯用方式是什么?

1 个答案:

答案 0 :(得分:2)

您可以将游标与循环一起使用,因此您将仅循环遍历现有记录,而无需检查NULL。 像这样:

DELIMITER \\
CREATE PROCEDURE dt1()
BEGIN
    DECLARE t VARCHAR(30);
    DECLARE done INT DEFAULT FALSE;
    DECLARE cur1 CURSOR FOR SELECT tag FROM `article` ORDER BY id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur1;

    loop1: LOOP
        FETCH cur1 INTO t;
        IF done THEN
            LEAVE loop1;
        END IF;

        SELECT COUNT(*) INTO @cnt from `article_tag` WHERE tag = t;

        IF @cnt = 0  THEN 
            INSERT INTO `article_tag` (tag, slug, frequency) VALUES (t, t, 1);
        ELSE 
            UPDATE `article_tag` SET frequency = frequency + 1 WHERE tag = t;
        END IF;
    END LOOP;

    CLOSE cur1;
END
\\
DELIMITER ;

有关详细信息,请参见手册: https://dev.mysql.com/doc/refman/5.7/en/cursors.html

当然,如果可能的话,我会使用INSERT ON DUPLICATE UPDATE,如上所述。