PostGIS 触发器功能——达到最大堆栈深度

PostGIS Trigger Function -- max stack depth reached

尝试在 PostGIS 中创建动态触发器函数,但收到 "max_stack_depth" 错误消息。

我在 PostGRES/GIS 中有两个 table 具有几何的 testzone.carsurtest 和 political.localities,我正在尝试更新 'locality' 中的字段 testzone.carsurtest 从 'locality_name' 字段 political.localities 使用 ST_Intersects。我已经成功地能够专门为 testzone.carsurtest 创建一个触发器函数,但是我想创建一个动态触发器函数以用于多个 table 想要从本地更新 table .

CREATE OR REPLACE FUNCTION tf_locality_test()
  RETURNS trigger AS
$BODY$

DECLARE
    tbl text := TG_TABLE_NAME;
    scm text := TG_TABLE_SCHEMA;

BEGIN

EXECUTE 'UPDATE '|| quote_ident(cast(scm as text)) ||'.'|| quote_ident(cast(tbl as text)) ||' AS dyntbl
        SET locality = political.locality.locality_name
        FROM  political.locality 
        WHERE ST_Intersects(dyntbl.wkb_geometry, political.locality.wkb_geometry)';

    RETURN NEW;
 END;
 $BODY$
   LANGUAGE plpgsql VOLATILE
   COST 100;
 ALTER FUNCTION tf_locality_test() OWNER TO postgres;

当我在 QGIS 中创建新的多边形记录时,我收到以下错误信息:

>

 Could not commit changes to layer carsurtest
> 
> Errors: ERROR: 1 feature(s) not added.
>      Provider errors:
>       PostGIS error while adding features: ERROR:  stack depth limit exceeded
>     HINT:  Increase the configuration parameter "max_stack_depth", after ensuring the platform's stack depth limit is adequate.
>     CONTEXT:  PL/pgSQL function "tf_locality_test" line 8 at EXECUTE statement
>     SQL statement "UPDATE test_zone.carsurtest AS dyntbl
>     SET locality = political.locality.locality_name
>     FROM  political.locality 
>     WHERE ST_Intersects(dyntbl.wkb_geometry, political.locality.wkb_geometry)"

如有任何建议,我们将不胜感激。 谢谢, 克里斯

这里的问题是您在 table 上有一个 BEFORE UPDATE 触发器,它有一个语句来更新相同的 table: 递归。一段时间后,等待 EXECUTE 语句完成的触发器太多(每个都调用相同的触发器函数)以至于堆栈被填满。不要在触发函数中执行动态 UPDATE,只需使用 NEW 隐式参数设置字段 locality 的值:

CREATE OR REPLACE FUNCTION tf_locality_test() RETURNS trigger AS $BODY$
BEGIN
  SELECT loc.locality_name INTO NEW.locality
  FROM political.localities loc
  WHERE ST_Intersects(NEW.wkb_geometry, loc.wkb_geometry);
  RETURN NEW;
END;
$BODY$ LANGUAGE plpgsql;

只要其他 table 的 localitywkb_geometry 列具有足够的定义,那么每个列都可以有一个 BEFORE UDPATE 触发器来调用同一个触发器功能。