Joe*_*cop 5 postgresql triggers postgis plpgsql
我有一张桌子:
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)
)
Run Code Online (Sandbox Code Playgroud)
PostGIS 2.0几何体yt_albers_geom是使用触发器创建的,该触发器针对此表触发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,将更新所有坐标字段.似乎这些触发器中的任何一个都会导致无限循环的触发器触发,对吗?
您可以使用标准触发器 执行此操作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
);
Run Code Online (Sandbox Code Playgroud)
当更新是为了
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();
Run Code Online (Sandbox Code Playgroud)
该WHEN条款是可选的.在没有实际更改值时阻止触发器触发.
当对
wgs84_latitude或进行更新时,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();
Run Code Online (Sandbox Code Playgroud)
沿着这些方向触发第三个要求......
INSERT INTO soil_samples VALUES (1, 1,1,1, 2,2, 3) RETURNING *;
Run Code Online (Sandbox Code Playgroud)
触发upbef_utm:空更新,没有任何反应:
UPDATE soil_samples SET utm_zone = 1 RETURNING *;
Run Code Online (Sandbox Code Playgroud)
更新实际更改:第二个触发器upbef_wgs84不会触发UPDATE OF utm_zone!
UPDATE soil_samples SET utm_zone = 0 RETURNING *;
Run Code Online (Sandbox Code Playgroud)
触发器upbef_wgs84:
UPDATE soil_samples SET wgs84_latitude = 0 RETURNING *;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1896 次 |
| 最近记录: |