MySQL : 级联更新相同 table

MySQL : Cascade update on same table

我有一个 MySQL table,其中每个记录都引用其 parent_id :

| id | Summary | parent_id | hidden |

-------------------------------------

|  1 | First   |      NULL |      0 |

|  2 | Hello   |         1 |      0 |

|  3 | john    |         1 |      0 |

|  4 | Second  |      NULL |      0 |

|  5 | World   |         2 |      0 |

|  6 | Doe     |         4 |      0 |

我想级联更新,这样如果第 1 行被隐藏,它的子项(第 2 行)和它的子项的子项(第 5 行)也会被隐藏。

MySQL是否可行。

我已经有一个 DELETE ON CASCADE constraint 可以正常工作。

CONSTRAINT FK_ID_With_CascadeDelete FOREIGN KEY (parent_id) REFERENCES MyTable (id) ON DELETE CASCADE

我认为你根本做不到。即使使用 UPDATE TRIGGER,您也无法更新同一 table 上的其他行。 也许这不是您期望的答案,但您最好的选择可能是使用这样的过程:

DELIMITER //

CREATE PROCEDURE UpdateHiden(IN pid INT, IN phidden INT)
BEGIN
  UPDATE mytable
  SET HIDDEN = phidden 
  WHERE ID = pid OR parent_id = pid;
END; //

DELIMITER ;

查看 DB 上的示例 Fiddle here

您可以按如下方式使用存储过程。

DELIMITER $$

DROP PROCEDURE IF EXISTS `update_node`$$

CREATE PROCEDURE `update_node`(IN p_id INT) 

 proc: BEGIN

    DECLARE e_no_id CONDITION FOR SQLSTATE '45000';

    IF ( p_id IS NULL ) THEN
            SIGNAL e_no_id SET MESSAGE_TEXT = 'The id cannot be empty.';
            LEAVE proc;
        END IF;

    DROP TEMPORARY TABLE IF EXISTS del_temp_table;      

    CREATE TEMPORARY TABLE IF NOT EXISTS del_temp_table(
     id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
     delids INTEGER UNSIGNED NOT NULL,
     node INTEGER DEFAULT 0
    );

    SET @rept := @loopcount := 1;   
    INSERT INTO del_temp_table (delids, node) SELECT p_id, @rept;

    myloop: WHILE (1 = 1)
    DO      
        SELECT COUNT(id) AS cnt FROM test WHERE `parent_id` IN ( SELECT DISTINCT(delids) FROM del_temp_table WHERE node = @rept ) INTO @loopcount;  

        IF (@loopcount = 0) THEN
           LEAVE myloop;
        ELSE
           SET @rept := @rept + 1;
           SELECT GROUP_CONCAT(d1.delids) INTO @wherein FROM ( SELECT DISTINCT(delids) FROM del_temp_table WHERE node = (@rept - 1) ) AS d1;
           INSERT INTO del_temp_table (delids, node) SELECT id, @rept FROM test WHERE FIND_IN_SET( parent_id, @wherein ) > 0;
        END IF ;

    END WHILE myloop;   

    UPDATE test SET hidden = 1 WHERE id IN ( SELECT delids FROM del_temp_table );       

    END$$

DELIMITER ;

在这里,我使用临时 table 来存储递归节点,并通过使用 table 每次迭代来获取下一个子节点并将其插入到相同的 table.

我相信这可以帮助你。 将 table 姓名 test 替换为您的 table 姓名