在更改 table 后更新列的 POSTGRESQL 触发器
POSTGRESQL Trigger that updates a column after having altered the table
我有一个已填充的 table,其中已经有一些特定的列。我想通过添加一个新列来更改 table 结构,该列将表示一个字段,该字段是另一个 table.
的行数
是否可以通过触发器来实现,以便在 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;
Is it possible to implement it through a trigger in order to do it automatically after the alter command?
首先,您的触发器在 table 上的每个 update
之后触发,而不是在 alter table
之后触发。其次,无论如何触发此类 DDL 事件的意义不大。
如果您的 table 已经有数据,您可能需要在创建列后对其进行初始化,例如:
update mytable1 t1
set new_column = (select count(*) from mytable2 t2 where t2.field = t1.field)
至于触发器中您想要的逻辑:您需要使用 new
和 old
来引用原始 table 中更改的行 - 通常,您会期望更新不会影响任何行(如果 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
您不会根据添加 列的时间在触发器中自动设置此值。当第二个 table.
发生变化时,您将使用触发器来维护该值
过程是:
添加具有默认值的列:
alter table mytable1 add new_column int default 0;
将列的值初始化为当前值:
update mytable1 t1
set new_column = (select count(*) from mytable2 t2 where t2.field = t1.field);
在 mytable2
上添加 insert/update/delete 个触发器。关键逻辑是:
update mytable1
set cnt = cnt + 1
where t1.field = new.field;
update mytable1
set cnt = cnt - 1
where t1.field = old.field;
如果您没有外键关系,如果 field
值不在 table 中,您可能还需要在 mytable1
中插入一行。但是,我强烈建议使用显式 foreign key
约束来防止这种情况发生。
这个 increments/decrements 对 秒 进行更改时的值 table.
我有一个已填充的 table,其中已经有一些特定的列。我想通过添加一个新列来更改 table 结构,该列将表示一个字段,该字段是另一个 table.
的行数是否可以通过触发器来实现,以便在 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;
Is it possible to implement it through a trigger in order to do it automatically after the alter command?
首先,您的触发器在 table 上的每个 update
之后触发,而不是在 alter table
之后触发。其次,无论如何触发此类 DDL 事件的意义不大。
如果您的 table 已经有数据,您可能需要在创建列后对其进行初始化,例如:
update mytable1 t1
set new_column = (select count(*) from mytable2 t2 where t2.field = t1.field)
至于触发器中您想要的逻辑:您需要使用 new
和 old
来引用原始 table 中更改的行 - 通常,您会期望更新不会影响任何行(如果 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
您不会根据添加 列的时间在触发器中自动设置此值。当第二个 table.
发生变化时,您将使用触发器来维护该值过程是:
添加具有默认值的列:
alter table mytable1 add new_column int default 0;
将列的值初始化为当前值:
update mytable1 t1 set new_column = (select count(*) from mytable2 t2 where t2.field = t1.field);
在
mytable2
上添加 insert/update/delete 个触发器。关键逻辑是:update mytable1 set cnt = cnt + 1 where t1.field = new.field; update mytable1 set cnt = cnt - 1 where t1.field = old.field;
如果您没有外键关系,如果 field
值不在 table 中,您可能还需要在 mytable1
中插入一行。但是,我强烈建议使用显式 foreign key
约束来防止这种情况发生。
这个 increments/decrements 对 秒 进行更改时的值 table.