Postgres - 如何在插入时自动调用 ST_SetSRID(ST_MakePoint(lng, lat), 4326)?

a p*_*son 5 sql database postgresql postgis

我正在使用postGIS,并且我对SQL不是很熟悉。

markers只要我执行这样的操作(伪代码!),我就可以成功插入到我的表中:

'INSERT INTO markers(created_by, title, description, lat, lng, geography)\
       values($1, $2, $3, $4::decimal, $5::decimal, ST_SetSRID(ST_MakePoint($5::decimal, $4::decimal), $6))',
      [
        data.created_by,
        data.title,
        data.description,
        data.lat,
        data.lng,
        4326
      ]'
Run Code Online (Sandbox Code Playgroud)

如您所见,我正在ST_SetSRID(ST_MakePoint($5::decimal, $4::decimal), $6)根据我的应用程序代码进行操作。

我想避免这种情况,而是将其放在数据库端。由于我可以在数据库端执行诸如自动时间戳之类的操作,因此我想知道是否也可以ST_SetSRID(ST_MakePoint(lng, lat), 4326)在表本身上执行此操作。

这样,应用程序只需要提供lat和lng,数据库就会进行操作ST_SetSRID(ST_MakePoint())

谢谢

编辑:我不确定谁的答案标记为+1,因为两者都提供了非常好的帮助和建议。我希望未来的读者能够阅读这两本书并希望能学到一些东西!

Eva*_*oll 2

我想避免这种情况,而是将其放在数据库端。由于我可以在数据库端执行诸如自动时间戳之类的操作,因此我想知道是否也可以ST_SetSRID(ST_MakePoint(lng, lat), 4326)在表本身上执行此操作。

确实不是一个好主意,但我知道这听起来是个好主意,而且看起来很有吸引力。也就是说,您所做的工作超出了您需要做的工作。

CREATE TABLE markers (geom geography(POINT,4326) );
INSERT INTO markers(geom) VALUES (ST_MakePoint(0,0));
Run Code Online (Sandbox Code Playgroud)

正如您在此处看到的,geography默认 SRID 为 4326。您不必将其设置为 4326,尽管明确设置不会有什么坏处。此外,将输入转换为ST_MakePoint()十进制并不是一个主意。ST_MakePoint只接受double precision. 结果来自\df ST_MakePoint

                                                     List of functions
 Schema |     Name     | Result data type |                          Argument data types                           |  Type  
--------+--------------+------------------+------------------------------------------------------------------------+--------
 public | st_makepoint | geometry         | double precision, double precision                                     | normal
 public | st_makepoint | geometry         | double precision, double precision, double precision                   | normal
 public | st_makepoint | geometry         | double precision, double precision, double precision, double precision | normal
Run Code Online (Sandbox Code Playgroud)

所以你可以在这里看到,额外的演员实际上只是增加了更多的工作。你真正想要的只是简单地ST_MakePoint(lng,lat)放到一个geography(POINT,4326)列中。

任务的其余部分需要触发器。它还需要有一个额外的列纬度和长度。虽然我可以告诉你如何做,但我强烈建议你要这样做。

ALTER TABLE markers
  ADD COLUMN lat double precision,
  ADD COLUMN long double precision;

CREATE OR REPLACE FUNCTION do_stupid_stuff()
RETURNS trigger
AS $$
  BEGIN
    NEW.geom = ST_MakePoint(NEW.long, NEW.lat);
    RETURN NEW;
  END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER really_lazy
  AFTER INSERT ON markers
  FOR EACH ROW
  EXECUTE PROCEDURE do_stupid_stuff();
Run Code Online (Sandbox Code Playgroud)