【问题标题】:Postgis trigger : table and materialized viewPostgis 触发器:表和物化视图
【发布时间】:2021-10-14 08:45:12
【问题描述】:

我的“城市”有一个 postgis 多边形表。 我的“boreholl”有一个点表。

我创建了一个由空间连接定义的“mv”物化视图,如下所示:

SELECT boreholl.*,
cities.gid,
cities.insee_id,
cities.name
FROM boreholl, cities
WHERE st_intersects(boreholl.geom, cities.geom);

现在我想尽快更新我的“城市”多边形表的“城市名称”列, 此更改也发生在我的物化视图的“名称”列中。

据我了解,触发器必须在“城市”表上定义如下:

CREATE TRIGGER cities_trigger
after  update
on cities
FOR EACH STATEMENT. 
execute procedure trigger_fonction

现在我需要定义函数。这一步我需要你。 下面,一个建议的结构。但是缺少很多东西:

CREATE or replace FUNCTION  trigger_fonction
returns trigger
langage sql
AS $$
BEGIN
 if    then
update
end if ;
return new
refresh materialized view
END;
$$

非常感谢。

【问题讨论】:

    标签: sql postgresql triggers postgis materialized-views


    【解决方案1】:

    最简单的方法是在特定列上创建触发器,每次更新此列时mv 都会刷新。:

    CREATE OR REPLACE FUNCTION rebuild_materialized_view() 
    RETURNS TRIGGER AS $$
    BEGIN
      REFRESH MATERIALIZED VIEW mv;
      RETURN NEW;
    END; $$ LANGUAGE plpgsql;
    

    列特定触发器的正确​​语法是...OF colum_name ON table_name...,而不仅仅是...ON table_name...。此外,您可能还想在INSERT 的情况下刷新视图:

    CREATE TRIGGER cities_trigger
    AFTER INSERT OR UPDATE OF name ON cities
    FOR EACH STATEMENT 
    EXECUTE PROCEDURE rebuild_materialized_view();
    

    这种方法的缺点是mv 将被刷新,而不管更新的记录与boreholl 之间的交集如何。不过,根据您的桌子的大小,这应该不是问题。

    演示:db<>fiddle

    另一种(稍微复杂一点)的方法是使用TG_OP 的值。如果使用INSERT 调用触发器并且新记录与boreholl 相交,则物化视图mv 将被刷新。如果它是 UPDATE 并且更新的记录之前在 mv 中并且 name 已更改,mv 也会被刷新:

    CREATE OR REPLACE FUNCTION rebuild_materialized_view() 
    RETURNS TRIGGER AS $$
    BEGIN
      IF TG_OP ='INSERT' AND EXISTS (SELECT ST_Intersects(NEW.geom,b.geom) 
                                     FROM boreholl b) THEN
         REFRESH MATERIALIZED VIEW mv;
      ELSEIF TG_OP = 'UPDATE' AND 
           EXISTS (SELECT 1 FROM mv 
                   WHERE gid = NEW.gid AND NEW.name <> OLD.name) THEN
          REFRESH MATERIALIZED VIEW mv;
      END IF;
    
      RETURN NEW;
    END; $$ LANGUAGE plpgsql;
    
    CREATE TRIGGER cities_trigger
    AFTER INSERT OR UPDATE ON cities
    FOR EACH ROW EXECUTE PROCEDURE rebuild_materialized_view();
    

    演示:db&lt;&gt;fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-06
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      • 2016-12-09
      • 2016-02-06
      相关资源
      最近更新 更多