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进行更新时,将更新所有坐标字段.
似乎这些触发器中的任何一个都会导致无限循环的触发器触发,对吗?
解决方法
The manual on
CREATE TRIGGER
informs:
The trigger will only fire if at least one of the listed columns is
mentioned as a target of the UPDATE command.
进一步向下:
A column-specific trigger (one defined using the UPDATE OF column_name
Syntax) will fire when any of its columns are listed as targets in the
UPDATE command’s SET list. It is possible for a column’s value to
change even when the trigger is not fired,because changes made to the
row’s contents by BEFORE UPDATE triggers are not considered.
大胆强调我的.因此没有无限循环,因为触发器内的更新不会调用另一个触发器.
测试用例
创建测试表(简化,没有不相关的行):
CREATE TABLE soil_samples ( pgid SERIAL PRIMARY KEY,yt_albers_geom double precision );
第一个要求的虚拟触发器:
When an update is done to
utm_zone
,utm_easting
,orutm_northing
,thenwgs_84_latitude
,wgs84_longitude
,andyt_albers_geom
are updated by a trigger.
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子句是可选的.在没有实际更改值时阻止触发器触发.
第二个要求的虚拟触发器:
When an update is done to
wgs84_latitude
orwgs84_longitude
,then all
the utm_
fields are updated,as well asyt_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,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:
UPDATE soil_samples SET wgs84_latitude = 0 RETURNING *;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。