MySQL触发器-在触发器中使用递归查询来更新表

时间:2019-02-14 23:32:57

标签: mysql recursion

我正在使用最新的MySQL(8.0.15),并且有一个递归查询来更新user表,并且我想在我的user表中有一个{{1}时运行它},INSERTUPDATE查询针对它运行。

上下文:如您在代码片段中所看到的,我使用一种物化路径方法将分层数据存储在MySQL中。您可以通过查看数据来弄清楚问题所在。

因此,每次修改表时都需要运行此递归查询,以便保持正确的DELETELineage

当前问题是,在对原始查询进行一些故障排除后,我在this SO post上发现无法在表上调用Depth,因为这会导致无限循环,因此我需要在列之前加上SET

我似乎无法弄清楚如何做到这一点,并且在下面的示例中提供了当前的尝试。

编辑:由于db-fiddle的限制,我更新了以下代码,删除了new

DELIMITTER
| version() |
| :-------- |
| 8.0.13    |
select version();
CREATE TABLE user (
  `Id` INT primary key, 
  `Name` VARCHAR(55), 
  `ManagerUserID` INTEGER, 
  `Depth` INTEGER, 
  `Lineage` VARCHAR(255)
);
INSERT INTO user (
  `Id`, `Name`, `ManagerUserID`, `Depth`, 
  `Lineage`
) 
VALUES 
  ('1', 'User 1', NULL, 0, '1.'), 
  ('2', 'User 2', '1', 1, '1.2.'), 
  ('3', 'User 3', '4', 3, '1.2.4.3.'), 
  ('4', 'User 4', '2', 2, '1.2.4.'), 
  ('5', 'User 5', '2', 2, '1.2.5.');
Id | Name   | ManagerUserID | Depth | Lineage 
-: | :----- | ------------: | ----: | :-------
 1 | User 1 |          null |     0 | 1.      
 2 | User 2 |             1 |     1 | 1.2.    
 3 | User 3 |             4 |     3 | 1.2.4.3.
 4 | User 4 |             2 |     2 | 1.2.4.  
 5 | User 5 |             2 |     2 | 1.2.5.  
SELECT * from user;
CREATE TRIGGER after_user_update 
   AFTER UPDATE ON user
   FOR EACH ROW 
BEGIN
  UPDATE
    user
  SET
    new.Lineage = CONCAT(Id, '.'),
    new.Depth = 0
  WHERE
    new.ManagerUserID IS NULL;

  WITH RECURSIVE prev AS (
    SELECT
      *
    FROM
      user
    WHERE
      new.ManagerUserID IS NULL
    UNION
    SELECT
      t.new.Id,
      t.new.Name,
      t.new.ManagerUserID,
      p.new.Depth + 1 as Depth,
      CONCAT(p.new.Lineage, t.new.Id, '.')
    FROM
      prev p
      JOIN user t ON t.new.ManagerUserID = p.new.Id
  )
  UPDATE
    user t,
    prev p
  SET
    t.new.Depth = p.Depth,
    t.new.Lineage = p.Lineage
  WHERE
    t.new.Id = p.new.Id;
END
Can't update table 'user' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
UPDATE user SET `ManagerUserID` = '1' WHERE (`Id` = '3');
Id | Name   | ManagerUserID | Depth | Lineage 
-: | :----- | ------------: | ----: | :-------
 1 | User 1 |          null |     0 | 1.      
 2 | User 2 |             1 |     1 | 1.2.    
 3 | User 3 |             4 |     3 | 1.2.4.3.
 4 | User 4 |             2 |     2 | 1.2.4.  
 5 | User 5 |             2 |     2 | 1.2.5.  

db <>提琴here

0 个答案:

没有答案