FOR FOR EACH ROW的postgresql触发器会影响不受影响的行

时间:2016-12-29 12:54:36

标签: postgresql triggers

我使用INSERT / UPDATE触发器从包含WKT字符串的文本列填充几何列。但现在它覆盖所有行!

CREATE TABLE public.teams
(
  name text,
  coverage_wkt text,
  coverage_geom geometry(Polygon,4326)
)
CREATE TRIGGER trigger_insert_or_update_on_teams
AFTER INSERT OR UPDATE ON teams
FOR EACH ROW
WHEN (pg_trigger_depth() = 0)
EXECUTE PROCEDURE set_geom_columns();
CREATE FUNCTION set_geom_columns() RETURNS trigger AS $set_geom_columns$
BEGIN
    IF NEW.coverage_wkt IS NOT NULL THEN        
        NEW.name := 'im changed forever';       
        NEW.coverage_geom := ST_GeomFromText(NEW.coverage_wkt,4326);            
    END IF;        
    RETURN NEW;
END; $set_geom_columns$ LANGUAGE plpgsql;
INSERT INTO teams (coverage_wkt) VALUES ('POLYGON((17 59, 19 59, 19 60, 18 60, 17 59))');
INSERT INTO teams (coverage_wkt) VALUES ('POLYGON((18 59, 19 59, 19 60, 18 60, 18 59))');

运行上述命令会导致:

 name |                 coverage_wkt                 |   coverage_geom
      | POLYGON((17 59, 19 59, 19 60, 18 60, 17 59)) | 010300002...
      | POLYGON((18 59, 19 59, 19 60, 18 60, 18 59)) | 010300002...

填充的几何图形列具有相同的几何图形:最后插入的几何图形!这让我相信它每次触发都会影响所有行。但是从我读到的文档中可以看出:

  

为操作修改的每一行

调用标记为FOR EACH ROW的触发器一次

此外,虽然在“RETURN NEW”之后coverage_geom实际上是持久的,但我无法以相同的方式设置NEW.name。我不知道它是否相关。

1 个答案:

答案 0 :(得分:2)

“如果你想改变新纪录的价值,你需要一个BEFORE触发器 - ” 正如a_horse_with_no_name所指出的那样。