首页 > 解决方案 > 在更改表后更新列的 POSTGRESQL 触发器

问题描述

我有一个已经有一些特定列的填充表。我想通过添加一个新列来更改表结构,该列将表示一个字段,该字段是另一个表的行数。

是否可以通过触发器实现它以便在 alter 命令之后自动执行?我想出了这样的东西,但显然没有更新该列:

触发器的功能:

CREATE FUNCTION update_column() RETURNS TRIGGER AS
$BODY$
DECLARE
num INTEGER;
BEGIN
    SELECT COUNT(*) INTO num FROM mytable1, mytable2 WHERE mytable1.field = mytable2.field GROUP BY mytable1.field;
    UPDATE mytable1 SET new_column = num;
END;
$BODY$
LANGUAGE PLPGSQL;

触发:

CREATE TRIGGER insert
AFTER UPDATE
ON mytable1
FOR EACH ROW
EXECUTE PROCEDURE update_column();

和改变命令:

ALTER TABLE mytable1 ADD new_column INT;

标签: sqlpostgresqltriggerssql-updatealter-table

解决方案


是否可以通过触发器实现它以便在 alter 命令之后自动执行?

首先,您的触发器update在桌子上的每个之后触发,而不是在alter table. 其次,无论如何触发此类 DDL 事件并没有多大意义。

如果您的表已经有数据,您可能需要在创建列后对其进行初始化,例如:

update mytable1 t1
set new_column = (select count(*) from mytable2 t2 where t2.field = t1.field)

至于您在触发器中想要的逻辑:您需要使用newold引用原始表中已更改的行 - 通常,您希望更新不会影响任何行(如果field未更改),或者两行(如果是的话):

update mytable1 t1
set new_column = (select count(*) from mytable2 t2 where t2.field = t1.field)
where t1.field in (new.field, old.field) and new.field <> old.field

也就是说,我不推荐这样的设置。维护这样的派生信息既昂贵又乏味(你有一个update触发器,现在你也需要一个insert和一个delete触发器)。相反,您可以在需要时动态计算逻辑,或创建视图:

create view myview as
select t1.*, 
    (select count(*) from mytable2 t2 where t2.field = t1.field) as new_column
from mytable1 t1

推荐阅读