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)。
如何做对?
这不是触发器的工作方式。您应该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)
每次插入新记录时都需要更新列
您的描述与触发器定义相矛盾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用于表示,以显示附加的、功能相关的列。