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

时间:2021-05-21 13:10:32

标签: 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,它应该执行上述检查。

我一直在研究触发器,觉得它可能对我使用这个用例有所帮助,但我不知道如何去做。请帮忙。

1 个答案:

答案 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

相关问题