我有一个表 A、表 B 和一个连接表 A_B。
表A
| id | a_active |
| -- | -------- |
| a1 | true |
表 B
| id | b_active |
| -- | -------- |
| b1 | false |
表 A_B - 主键唯一(a_id
,b_id
)和分别引用 A 和 B 的外键。
| id | a_id_fk | b_id_fk | active |
| -- | ------- | ------- | ------ |
| j1 | a1 | b1 | false |
因此,每当 a_active
或 b_active
的值发生变化时,我都希望 active
根据条件 a_active && b_active
进行更改。
另外,我应该能够将 active
更改为 false
,但要更改为 true
,它应该执行上述检查。
我一直在研究触发器,觉得它可能对我使用这个用例有所帮助,但我不知道如何去做。请帮忙。
答案 0 :(得分:1)
推荐的方法是编写如下视图:
create view viewA_B as
select
t1.id,t1.a_id_fk,t1.b_id_fk, ((t2.a_active) and (t3.b_active)) "active"
from a_b t1
inner join tabA t2 on t2.id=t1.a_id_fk
inner join tabB t3 on t3.id=t1.b_id_fk
然后您可以使用如下视图:
select * from viewA_B where active=false;
但是您仍然想编写触发器。然后你必须写2个触发器。一个在 tableA 上,第二个在 tableB 上。使用这个link
表A的触发函数
CREATE OR REPLACE FUNCTION updateA()
RETURNS TRIGGER
AS
$$
BEGIN
update a_b t1
SET "active" = (new.a_active and t2.b_active)
from tabB t2 where t2.id=t1.b_id_fk and t1.a_id_fk=NEW.id;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
在表 A 上触发
CREATE TRIGGER trg_update_a
AFTER UPDATE ON tabA
FOR EACH ROW
EXECUTE PROCEDURE updateA();
B表的触发函数
CREATE OR REPLACE FUNCTION updateB()
RETURNS TRIGGER
AS
$$
BEGIN
update a_b t1
SET "active" = (new.b_active and t2.a_active)
from tabA t2 where t2.id=t1.a_id_fk and t1.b_id_fk=NEW.id;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
在表 B 上触发
CREATE TRIGGER trg_update_b
AFTER UPDATE ON tabB
FOR EACH ROW
EXECUTE PROCEDURE updateB();
编辑:根据评论
您想在 a_b
中验证更新,那么您可以使用 check
约束。
首先创建一个如下所示的函数:
CREATE OR REPLACE FUNCTION validate_active(id_a varchar, id_b varchar,val bool)
RETURNS BOOLEAN AS $$
declare check_b bool;
declare check_a bool;
begin
select a_active into check_a from tabA where id=id_a;
select b_active into check_b from tabB where id=id_b;
if val then
return (check_b and check_a);
else
return true;
end if;
end;
$$ LANGUAGE plpgsql;
然后更改您的表格并添加如下检查约束:
alter table a_b add CONSTRAINT valid_val CHECK(validate_active(a_id_fk,b_id_fk,active))
上面将根据您的情况检查表 active
中字段 a_b
的更改。
DEMO