postgresql触发器,用于在插入时填充新列

时间:2016-04-30 10:23:58

标签: postgresql triggers

我有一张表Table_A

\d "Table_A";
                           Table "public.Table_A"
  Column  |  Type   |                          Modifiers
----------+---------+-------------------------------------------------------------
 id       | integer | not null default nextval('"Table_A_id_seq"'::regclass)
 field1   | bigint  |
 field2   | bigint  |

现在我想添加一个新列。所以我跑:

ALTER TABLE "Table_A" ADD COLUMN "newId" BIGINT DEFAULT NULL;

现在我有:

\d "Table_A";
                           Table "public.Table_A"
  Column  |  Type   |                          Modifiers
----------+---------+-------------------------------------------------------------
 id       | integer | not null default nextval('"Table_A_id_seq"'::regclass)
 field1   | bigint  |
 field2   | bigint  |
 newId    | bigint  |

我希望newId为新/更新的行填充与id相同的值。

我创建了以下函数并触发:

CREATE OR REPLACE FUNCTION autoFillNewId() RETURNS TRIGGER AS $$
BEGIN
  NEW."newId" := NEW."id";
  RETURN NEW;
END $$ LANGUAGE plpgsql;

CREATE TRIGGER "newIdAutoFill" AFTER INSERT OR UPDATE ON "Table_A" EXECUTE PROCEDURE autoFillNewId();

现在,如果我插入一些东西:

INSERT INTO "Table_A" values (97, 1, 97);

newId未填写:

select * from "Table_A" where id = 97;
 id | field1   | field2   | newId
----+----------+----------+-------
 97 |        1 |       97 |
  

注意:我也尝试了FOR EACH ROW来自SO

的答案

什么让我失望?

1 个答案:

答案 0 :(得分:5)

您需要一个BEFORE INSERT OR UPDATE ... FOR EACH ROW触发器来完成这项工作:

CREATE TRIGGER "newIdAutoFill"
INSERT OR UPDATE ON "Table_A"
FOR EACH ROW EXECUTE PROCEDURE autoFillNewId();

在插入或更新新行之前会发生BEFORE触发器,因此您仍然可以更改字段值。 AFTER触发器可用于实现某些副作用,例如审核更改或对其他表进行级联更改。

默认情况下,触发器为FOR EACH STATEMENT,然后未定义NEW参数(因为触发器不在一行上运行)。所以你必须指定FOR EACH ROW