Postgresql

連接表在另一個表中更新後觸發

  • April 23, 2021

我只是想創建一個在聯結表中執行更新的觸發器。

原則上,我有三個具有多對多關係的表。

Table a:
a_id, a_is_active
Table b:
b_id, b_is_active
Table ab:
ab_id, a_id, b_id, ab_is_active

我想要的是ab_is_active需要在更新a_is_activeb_is_active更新時實現,所以ab_is_active應該是這樣的(虛擬碼):

ab_is_active = a_is_acvite && b_is_acvite where a_id = a.a_id and b_id = b.b_id

並且必須is_active在表 a 或表 b 中的每次更新後執行:

我嘗試了以下方法,但它不起作用(ab 中沒有任何更新):

CREATE OR REPLACE FUNCTION is_active_changes()
   returns trigger
   language plpgsql AS
$BODY$
DECLARE
   b_is_active boolean;
   r            b%ROWTYPE;
BEGIN
   for r in select *
            into b_is_active 
            from ab
                     join b _b on ab.b_id= _b.b_id
                     join a _a on ab.a_id= _a.a_id
       LOOP
               update ab set ab_is_active = r.a_is_active and r.b_is_active where b_id = r.b_id and a_id = r.a_id;
       END LOOP;
END;
$BODY$;

create trigger is_active_trigger
   after update
   on a
   for each row
execute procedure is_active_changes();

有人可以告訴我我做錯了什麼或提出更好的解決方案嗎?

你的問題是,你犯了一些小錯誤

在 for 循環中,您需要選擇適合行類型的那些列

我最後添加了一個更好的版本,因為它只更新一行,而不是所有存在 b.id 和 a.id 的地方

CREATE Table a
("a_id" INT, "a_is_active" Boolean)
CREATE Table b
("b_id" INT, "b_is_active" Boolean)
CREATE Table ab
("ab_id" INT , "a_id" int, "b_id" int, "ab_is_active" Boolean)
INSERT INTO a VALUES (1,TRUE)
INSERT INTO B VALUES (1,TRUE)
INSERT INTO ab VALUES (1,1,1,FALSE)
DO
$BODY$
DECLARE
    b_is_active boolean;
    r            ab%ROWTYPE;
BEGIN
    for r in select ab.ab_id, ab.b_id,ab.a_id,_a.a_is_active AND _b.b_is_active AS ab_is_active
             from ab
                      join b _b on ab.b_id= _b.b_id
                      join a _a on ab.a_id= _a.a_id
        LOOP
                update ab set ab_is_active = r.ab_is_active 
                where b_id = r.b_id AND a_id = r.a_id;
        END LOOP;
END;
$BODY$;
SELECT * FROM ab
ab_id | a_id | b_id | ab_is_active
----: | ---: | ---: | :-----------
 1 | 1 | 1 | 噸 
DO
$BODY$
DECLARE
    b_is_active boolean;
    r            ab%ROWTYPE;
BEGIN
    for r in select ab.ab_id, ab.b_id,ab.a_id,_a.a_is_active AND _b.b_is_active AS ab_is_active
             from ab
                      join b _b on ab.b_id= _b.b_id
                      join a _a on ab.a_id= _a.a_id
        LOOP
                update ab set ab_is_active = r.ab_is_active 
                where ab_id = r.ab_id;
        END LOOP;
END;
$BODY$;

db<>在這裡擺弄

引用自:https://dba.stackexchange.com/questions/290353