我有一个表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
,它应该执行上述检查。
我在研究触发器,觉得它可能会对我的这个用例有所帮助,但我不知道该怎么做。请帮忙。
如果您只想要活动数据(我认为这是有意的(,请使用:
select ab.*
from a_b ab join
a
on ab.a_id_fk = a.id join
b
on ab.b_id_fk = b.id
where a.active and b.active;
存储具有该信息的冗余列CCD_ 10几乎没有什么好处。当a
或b
中的数据发生变化时,它会增加开销——实际上可能会有很多变化。它使每一列都更宽,因此表占用更多的空间。并且加入到a
和b
应该相当快。
编辑:
根据您的评论,您有三个活动标志,因此where
将是:
where a.active and b.active and ab.active
推荐的方法是编写如下视图:
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;
但你仍然想写触发器。然后你必须写两个触发器。一个在表A上,第二个在表B上。使用此链接
表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))
以上将根据您的情况检查表a_b
中字段active
的更改。演示