触发函数更新列

Fel*_*ida 5 trigger plpgsql functions postgresql-9.5

我是 PL/pgSQL 的新手……我使用 Postgres 9.5.0,每次插入新记录时都需要更新一列。该列应从area_pol和 中输入的值中填写area_ofi

我正在尝试创建此功能以适合我的情况:

CREATE OR REPLACE FUNCTION sch_cap.fc_atualiza_dif_area()
  RETURNS trigger AS
$$
BEGIN
    UPDATE
        sch_cap.tbl_cap
    SET
        dif_area = abs(100 - (tbl_cap.area_pol / (tbl_cap.area_ofi * 100)));
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER tg_atualiza_dif_area
  BEFORE INSERT OR UPDATE ON sch_cap.tbl_cap
  FOR EACH ROW EXECUTE PROCEDURE sch_cap.fc_atualiza_dif_area();
Run Code Online (Sandbox Code Playgroud)

但是当我尝试插入记录时,出现以下错误:

错误:超出堆栈深度限制
提示:在确保平台的堆栈深度限制足够后,增加配置参数“max_stack_depth”(当前为 2048kB)。

如何做对?

Eva*_*oll 6

这不是触发器的工作方式。您应该TRIGGER在更新之前触发,然后您只需SET在 NEW 记录上使用。

SET new.dif_area = abs(100 - (OLD.area_pol / (OLD.area_ofi * 100)));
Run Code Online (Sandbox Code Playgroud)

但更好的是,完全放弃它并使用VIEW.

CREATE VIEW sch_cap.tbl_cap AS
  SELECT *, abs(100 - (area_pol / (area_ofi * 100))) AS dif_area
  FROM tbl_cap;
Run Code Online (Sandbox Code Playgroud)


Erw*_*ter 3

每次插入新记录时都需要更新列

您的描述与触发器定义相矛盾BEFORE INSERT OR UPDATE。要么只是描述BEFORE INSERT,要么描述是错误的。

接下来,你的整个触发功能是一个误解。只会是:

CREATE OR REPLACE FUNCTION sch_cap.fc_atualiza_dif_area()
  RETURNS trigger AS
$func$
BEGIN
   NEW.dif_area := abs(100 - (NEW.area_pol / (NEW.area_ofi * 100)));
END
$func$  LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

只需在插入行之前分配所需的值即可。SET这里没有。)

但实际上,我会使用埃文VIEW建议的
至于您的评论,如果 QGIS 以某种方式扰乱了可更新视图的自动功能(就像您在gis.SE 的相关问题中所述),请继续直接写入表。在这种情况下仅VIEW用于表示,以显示附加的、功能相关的列。