我有一张桌子:
CREATE TABLE field_data.soil_samples (
pgid SERIAL NOT NULL,
sample_id text,
project_id text,
utm_zone integer,
utm_easting integer,
utm_northing integer,
wgs84_longitude double precision,
wgs84_latitude double precision,
yt_albers_geom geometry(Point,3578),
CONSTRAINT soil_samples_pk PRIMARY KEY (pgid)
)
yt_albers_geom
中的PostGIS 2.0几何体是使用触发器创建的,该触发器针对此表触发INSERTS。如果要插入的记录满足以下条件之一,则会生成几何图形:
wgs84_latitude
和wgs84_longitude
字段均不为空utm_zone
,utm_easting
和utm_northing
均不为空现在,我对如何进行更新以实现以下目标感到困惑:
utm_zone
,utm_easting
或utm_northing
进行更新后,wgs_84_latitude
,wgs84_longitude
和yt_albers_geom
将更新为触发器wgs84_latitude
或wgs84_longitude
进行了更新,则会更新所有utm_
字段以及yt_albers_geom
。yt_albers_geom
进行更新后,所有坐标字段都会更新。似乎这些触发器中的任何一个都会导致触发器触发无限循环,对吗?
答案 0 :(得分:5)
您可以使用标准触发器 BEFORE UPDATE OF ... ON ...
执行此操作
The manual on CREATE TRIGGER
informs:
只有至少有一个列出的列时,触发器才会触发 提到作为UPDATE命令的目标。
进一步向下:
特定于列的触发器(使用UPDATE OF column_name定义的触发器 语法)将在其任何列被列为目标中时触发 UPDATE命令的SET列表。列的值可能是 即使未触发触发器也会更改,因为对其进行了更改 不考虑BEFORE UPDATE触发器的行内容。
大胆强调我的。所以没有无限循环,因为触发器内的更新不会调用另一个触发器。
创建测试表(简化,没有不相关的行):
CREATE TABLE soil_samples (
pgid SERIAL PRIMARY KEY
,utm_zone integer
,utm_easting integer
,utm_northing integer
,wgs84_longitude double precision
,wgs84_latitude double precision
,yt_albers_geom double precision
);
如果对
utm_zone
,utm_easting
或utm_northing
进行了更新,那么 <{1}},wgs_84_latitude
和wgs84_longitude
由触发器更新。
yt_albers_geom
CREATE OR REPLACE FUNCTION trg_upbef_utm() RETURNS trigger AS
$func$
BEGIN
NEW.wgs84_latitude := NEW.wgs84_latitude + 10;
NEW.wgs84_longitude := NEW.wgs84_longitude + 10;
NEW.yt_albers_geom := NEW.yt_albers_geom + 10;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER upbef_utm
BEFORE UPDATE OF utm_zone, utm_easting, utm_northing ON soil_samples
FOR EACH ROW
WHEN (NEW.utm_zone IS DISTINCT FROM OLD.utm_zone OR
NEW.utm_easting IS DISTINCT FROM OLD.utm_easting OR
NEW.utm_northing IS DISTINCT FROM OLD.utm_northing) -- optional
EXECUTE PROCEDURE trg_upbef_utm();
子句是可选的。当没有值实际发生变化时,阻止触发器触发。
对
WHEN
或wgs84_latitude
进行更新后,全部更新 更新了uwgs84_longitude
字段,以及tm_
。
yt_albers_geom
沿着这些方向触发第三项要求......
CREATE OR REPLACE FUNCTION trg_upbef_wgs84() RETURNS trigger AS
$func$
BEGIN
NEW.utm_zone := NEW.utm_zone + 100;
NEW.utm_easting := NEW.utm_easting + 100;
NEW.utm_northing := NEW.utm_northing + 100;
NEW.yt_albers_geom := NEW.yt_albers_geom + 100;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER upbef_wgs84
BEFORE UPDATE OF wgs84_latitude, wgs84_longitude ON soil_samples
FOR EACH ROW
WHEN (NEW.wgs84_latitude IS DISTINCT FROM OLD.wgs84_latitude OR
NEW.wgs84_longitude IS DISTINCT FROM OLD.wgs84_longitude) -- optional
EXECUTE PROCEDURE trg_upbef_wgs84();
触发器INSERT INTO soil_samples VALUES (1, 1,1,1, 2,2, 3) RETURNING *;
:空更新,没有任何反应:
upbef_utm
使用实际更改进行更新:UPDATE soil_samples SET utm_zone = 1 RETURNING *;
不会触发第二个触发器upbef_wgs84
!
UPDATE OF utm_zone
触发UPDATE soil_samples SET utm_zone = 0 RETURNING *;
:
upbef_wgs84