2017-01-18 25 views
0

我有一个BEFORE触发器,它应填写记录的根ID其中,当然,将指向rootmost条目。即:Postgres的INSERT触发器填充ID

id | parent_id | root_id 
------------------------- 
a  | null  | a 
a.1 | a   | a 
a.1.1 | a.1  | a 
b  | null  | b 

如果条目的parent_id为空,它会指向记录自己。

问题是 - 在BEFORE INSERT触发器中,如果parent_id为空,我能否或应该取下一个序列值,填入id和root_id以避免在AFTER触发器中填写root_id?

+0

做序列怎么来的在这里的图片? – e4c5

回答

0

根据您自己的定义:

如果条目的PARENT_ID为空,它会指向其自身记录

然后你要做的:

if new.parent_id is null then 
    new.root_id = new.id ; 
else 
    WITH RECURSIVE p (parent_id, level) AS 
    (
    -- Base case 
    SELECT 
     parent_id, 0 as level 
    FROM 
     t 
    WHERE 
     t.id = new.id 
    UNION ALL 
    SELECT 
     t.parent_id, level + 1 
    FROM 
     t JOIN p ON t.id = p.parent_id 
    WHERE 
     t.parent_id IS NOT NULL 
) 
    SELECT 
    parent_id 
    INTO 
    new.root_id 
    FROM 
    p 
    ORDER BY 
    level DESC 
    LIMIT 
    1 ; 
end if ; 
RETURN new ; 
+0

对不起,我没有足够的重音。我的问题是,如何在BEFORE触发器中完成所有这些。 New.id在触发前是空的。还是不是? – JohnSmith

+0

@约翰史密斯:不应该。 'id'是一个'serial'(或'bigserial'或'smallserial')?如果是这样,它有一个默认值,因此,*是*定义的。 – joanolo