如何根据其他表中属性的更改触发表中某行属性的更新

  • 本文关键字:属性 更新 何根 其他 sql postgresql
  • 更新时间 :
  • 英文 :


我有一个表a、表B和一个联接表a_B。

表A

| id | a_active |
| -- | -------- |
| a1 | true     |

表B

| id | b_active |
| -- | -------- |
| b1 | false    |

表A_B-主键唯一(a_idb_id(和外键分别引用A和B。

| id | a_id_fk | b_id_fk | active |
| -- | ------- | ------- | ------ |
| j1 | a1      | b1      | false  | 

因此,每当a_activeb_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几乎没有什么好处。当ab中的数据发生变化时,它会增加开销——实际上可能会有很多变化。它使每一列都更宽,因此表占用更多的空间。并且加入到ab应该相当快。

编辑:

根据您的评论,您有三个活动标志,因此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的更改。演示

最新更新