PostgreSQL触发执行过程或加入NEW

时间:2019-02-12 05:23:37

标签: postgresql postgis database-trigger

-- trigger function
CREATE OR REPLACE FUNCTION fn_cities_geo_update_event() RETURNS trigger AS $fn_cities_geo_update_event$
  BEGIN

可以设置一个稍后将在函数中使用的值(geog)吗?

    NEW.geog := ST_SetSRID(ST_MakePoint(NEW.longitude,NEW.latitude), 4326)::geography;

这是我尝试查找距新城市90公里以内的所有城市的平均值的一种方法,以便该新城市具有有关该城市的数据

  if NEW.rent_avg IS null then
    NEW.rent_avg = (
      SELECT avg(a.rent_avg)
      FROM cities as a
-- I think I'm missing something here... ?
      ST_DWithin(a.geog, NEW.geog, 90000)
      );
  end if;

这是我尝试过的另一种方法:

  if NEW.food_avg IS null then
  NEW.food_avg := (
    SELECT avg(a.food_avg)
    FROM    cities AS a
    JOIN    NEW AS b
      ON    ST_DWithin(a.geog, b.geog, 90000)
    );
  end if;
  RETURN NEW;
  END;
$fn_cities_geo_update_event$ LANGUAGE plpgsql;

但都不起作用。

编辑:这是我正在使用的表的副本

l    |u |n                         |population|unesco|r                        |c               |rent_avg|rent_low|rent_high|food_avg|food_low|food_high|transport_avg|transport_low|transport_high|k        |i  |quality|hcid                                 |hc  |latitude   |longitude |spread     |density   |distance  |dbn                       |state|geog                                              |id   
-----|--|--------------------------|----------|------|-------------------------|----------------|--------|--------|---------|--------|--------|---------|-------------|-------------|--------------|---------|---|-------|-------------------------------------|----|-----------|----------|-----------|----------|----------|--------------------------|-----|--------------------------------------------------|-----
false|NZ|Gisborne                  |     34274|     0|Australia and New Zealand|New Zealand     | 92.2430| 51.1720| 143.4150| 22.0300| 13.3190|  35.3490|       7.0650|       5.9800|       13.0450|4VHV8X00+|GIS|   1712|place:Gisborne                       |  46|-38.6640015|177.977005| 0.99940002|         0|          |                          |     |0101000020E6100000000000A0433F664000000000FE5443C0| 1611
true |NZ|Patutahi                  |       386|      |Australia and New Zealand|New Zealand     |        |        |         |        |        |         |             |             |              |4VHV9V00+|   |   1000|place:Patutahi                       |  35|-38.6170006|177.899994|           |          |       8.5|Patutahi                  |     |0101000020E6100000000000C0CC3C6640000000E0F94E43C0| 1624
true |NZ|Waihau Bay                |          |      |Australia and New Zealand|New Zealand     |        |        |         |        |        |         |             |             |              |4VJV8Q00+|   |   1000|place:Waihau_Bay                     |   6|-37.6780014|177.796005|           |          |110.699997|Waihau Bay                |     |0101000020E6100000000000E078396640000000C0C8D642C0| 1671
true |NZ|Tokomaru Bay              |       495|      |Australia and New Zealand|New Zealand     |        |        |         |        |        |         |             |             |              |4VHWV800+|   |   1000|place:Tokomaru_Bay                   |   5|-38.1329994|178.300003|           |          |65.4000015|Tokomaru Bay              |     |0101000020E6100000000000A09949664000000020061143C0| 1673
true |FR|Cornebarrieu              |          |      |Western Europe           |France          |        |        |         |        |        |         |             |             |              |8FM3M800+|   |   1000|place:Cornebarrieu                   | 112| 43.6559982|1.33299994| 3.60581994|          | 3.5999999|Cornebarrieu              |     |0101000020E6100000000000C0F753F53F000000C0F7D34540| 6070

编辑:创建触发器语句

DROP TRIGGER IF EXISTS tr_cities_inserted ON cities;
CREATE TRIGGER tr_cities_inserted
  BEFORE INSERT ON cities
  FOR EACH ROW
  EXECUTE PROCEDURE fn_cities_geo_update_event();

1 个答案:

答案 0 :(得分:1)

好吧,这很有趣。.我是触发器的新手(您可能已经注意到^^),因此看来,当我为该表创建触发器后重新创建表时,该触发器不起作用。它只是为各个列返回null。

当我坚持正确的命令时,我将其与您案件的样品复制品一起使用:

CREATE TABLE so_postgres
(n text,
 r text,
 c text,
 rent_avg numeric,
 food_avg numeric,
 transport_avg numeric,
 latitude numeric,
 longitude numeric,
 geog geography
 );

 INSERT INTO so_postgres
 VALUES  ('Möhringen', 'central europe', 'germany', 200.45, 56.45, 4.56, 48.725866, 
           9.146131, ST_SetSRID(ST_Point(9.146131, 48.725866), 4326)),
         ('Vaihingen', 'central europe', 'germany', 155.33, 44.12, 2.78, 48.732550,
           9.108291, ST_SetSRID(ST_Point(9.108291, 48.732550), 4326)),
         ('Sigmaringen', 'central europe', 'germany', 298.11, 59.67, 1.99, 48.090797, 
           9.230243, ST_SetSRID(ST_Point(9.230243, 48.090797), 4326));

CREATE OR REPLACE FUNCTION fn_cities_geo_update_event() RETURNS trigger AS $fn_cities_geo_update_event$


BEGIN


NEW.geog := (ST_SetSRID(ST_MakePoint(NEW.longitude,NEW.latitude), 4326)::geography);

  if NEW.rent_avg IS null then
    NEW.rent_avg := (
      SELECT round(avg(a.rent_avg), 2)
      FROM so_postgres as a
      WHERE ST_DWithin(a.geog, NEW.geog, 50000)
      );
  end if;

 RETURN NEW;
  END;
$fn_cities_geo_update_event$ LANGUAGE plpgsql;


CREATE TRIGGER fn_cities_geo_update_event BEFORE INSERT OR UPDATE ON so_postgres FOR EACH ROW EXECUTE PROCEDURE fn_cities_geo_update_event();

 INSERT INTO so_postgres (n, r, c, latitude, longitude)
 VALUES ('Degerloch', 'central europe', 'germany', 48.725866, 9.146131); 

      n      |       r        |    c    | rent_avg | food_avg | transport_avg | latitude  | longitude |                        geog
-------------+----------------+---------+----------+----------+---------------+-----------+-----------+----------------------------------------------------
 Möhringen   | central europe | germany |   200.45 |    56.45 |          4.56 | 48.725866 |  9.146131 | 0101000020E610000012DDB3AED14A2240A1A3552DE95C4840
 Vaihingen   | central europe | germany |   155.33 |    44.12 |          2.78 | 48.732550 |  9.108291 | 0101000020E6100000FBE6FEEA71372240A857CA32C45D4840
 Sigmaringen | central europe | germany |   298.11 |    59.67 |          1.99 | 48.090797 |  9.230243 | 0101000020E61000000F441669E275224097C9703C9F0B4840
 Degerloch   | central europe | germany |   177.89 |          |               | 48.725866 |  9.146131 | 0101000020E610000012DDB3AED14A2240A1A3552DE95C4840

要回答您的最后一条评论:我通过ST_DWithin子句将WHERE添加到查询的其余部分。

它对您有用吗?