Mysql 如何处理存储过程循环中丢失的行?

Mysql 如何处理存储过程循环中丢失的行?,mysql,stored-procedures,Mysql,Stored Procedures,我有一个过程,它循环遍历文章值,获取tag1并将其插入文章标签表: 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

我有一个过程,它循环遍历
文章
值,获取
tag1
并将其插入
文章标签
表:

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$$

我想知道处理这些丢失行的惯用方法是什么?

您可以使用带游标的循环,这样您将只循环现有记录,而不需要检查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 ;
有关详细信息,请参阅手册:


当然,如果可能的话,我会像前面提到的那样在重复更新时使用INSERT。

您可以使用带游标的循环,这样您将只循环现有记录,而不需要检查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 ;
有关详细信息,请参阅手册:


当然,如果可能的话,我会像前面提到的那样在重复更新时使用INSERT。

添加一个条件并跳过它?@tadman什么条件?类似于
t为NULL的东西。
。我只是注意到,不管情况如何,这可能是一个单一的查询<代码>插入文章标签(标签、段塞、频率)从文章中选择tag1、tag1,1,其中tag1在重复键更新频率=frequency+1上不为空。不确定,为什么不使用光标而不是手动迭代?添加一个条件并跳过它?@tadman什么条件?类似于
t为NULL
。我只是观察到这可能是一个单独的查询,而不管情况如何<代码>插入文章标签(标签、段塞、频率)从文章中选择tag1、tag1,1,其中tag1在重复键更新频率=frequency+1上不为空。不确定,为什么不使用光标而不是手动迭代?非常有趣。作为SP的初学者,我以前从未遇到过循环/游标。谢谢非常有趣。作为SP的初学者,我以前从未遇到过循环/游标。谢谢