一尘不染

PostgreSQL更新触发器

sql

我有一张桌子:

CREATE TABLE annotations
(
  gid serial NOT NULL,
  annotation character varying(250),
  the_geom geometry,
  "rotationAngle" character varying(3) DEFAULT 0,
  CONSTRAINT annotations_pkey PRIMARY KEY (gid),
  CONSTRAINT enforce_dims_the_geom CHECK (st_ndims(the_geom) = 2),
  CONSTRAINT enforce_srid_the_geom CHECK (st_srid(the_geom) = 4326)
)

并触发:

CREATE TRIGGER set_angle
AFTER INSERT OR UPDATE
ON annotations
FOR EACH ROW
EXECUTE PROCEDURE setangle();

和功能:

CREATE OR REPLACE FUNCTION setAngle() RETURNS TRIGGER AS $$
BEGIN
IF    TG_OP = 'INSERT' THEN
    UPDATE annotations SET "rotationAngle" = degrees( ST_Azimuth( ST_StartPoint(NEW.the_geom), ST_EndPoint(NEW.the_geom) ) )-90 WHERE gid = NEW.gid;
    RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
    UPDATE annotations SET "rotationAngle" = degrees( ST_Azimuth( ST_StartPoint(NEW.the_geom), ST_EndPoint(NEW.the_geom) ) )-90 WHERE gid = NEW.gid;
    RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;

并且当在表中插入新行或对行进行编辑时,我想rotationAngle使用函数结果设置字段。但是当我在表功能中插入新行时无法正常工作。我的意思是,rotationAngle价值没有改变。

有什么事吗


阅读 145

收藏
2021-03-17

共1个答案

一尘不染

正如@SpartanElite指出的那样,您正在触发一个无限循环。

简化触发功能:

CREATE OR REPLACE FUNCTION set_angle()
  RETURNS TRIGGER AS
$func$
BEGIN
   NEW."rotationAngle" := degrees(
                             ST_Azimuth(
                                ST_StartPoint(NEW.the_geom)
                              , ST_EndPoint(NEW.the_geom)
                             )
                          ) - 90;
   RETURN NEW;
END
$func$ LANGUAGE plpgsql;
  • NEW直接分配给。WHERE在这种情况下不可以。
  • 必须 双引号非法列名。最好不要使用此类名称开头。

  • 插入和升级的代码是相同的。我折叠成一个代码路径。

使用 BEFORE 触发器。这样,您可以 保存 之前 直接编辑触发行的列:

CREATE TRIGGER set_angle
**BEFORE** INSERT OR UPDATE ON annotations
FOR EACH ROW EXECUTE PROCEDURE set_angle();

然而

如果 您只是想将功能相关的值保留在表中(并且没有其他注意事项): 然后,您不需要任何这些。

2021-03-17