您可以使用标准触发器 BEFORE UPDATE OF ... ON ...
来执行此操作。
手册上CREATE TRIGGER
告知:
仅当列出的列中的至少一个列被提及为 UPDATE 命令的目标时,触发器才会触发。
再往下:
当它的任何列被列为 UPDATE 命令的 SET 列表中的目标时,将触发特定于列的触发器(使用 UPDATE OF column_name 语法定义的触发器)。即使未触发触发器,列的值也可能更改,因为不考虑 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
,则
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
or进行更新时wgs84_longitude
,所有 utm_
字段以及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
:
UPDATE soil_samples SET wgs84_latitude = 0 RETURNING *;
-> SQLfiddle 演示。