Kli*_*Max 9 sql postgresql triggers plpgsql
我有一张桌子:
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价值没有改变.
有什么不对?
Erw*_*ter 21
正如@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();如果您只是试图在表中保持功能相关的值(并且没有其他考虑因素):不要.改为使用视图或生成的列:
那你就不需要了.
这里有很多问题。1)当您插入行“A”时,setAngle()将调用该函数。但是在函数中,您正在调用update函数内的另一个函数,这将再次触发该函数,等等......要解决此问题,请不要发布更新!只需独立更新 NEW 记录值并返回即可。