PostgreSQL 10.12を使用しています。
地理データを含む特定のテーブルでトリガー関数を起動できるようにしたい。
このトリガー関数は、geom
とlat
の値から列lon
に PotGIS ポイントを作成するように設計されています。
新しい行が挿入されるたびに、これと同じトリガー関数を複数のテーブルに適用したいと思います。
緯度と経度の値を保持する列の名前はテーブル間で一貫していませんが、パターンに従います...
私が100%確信しているのは、
1。常に緯度と経度の値を含む2つの列があり、
2。これらの列の名前は常に同じではありません別のテーブルでは同じです(そうでない場合は単純すぎるでしょう)、「緯度」という単語と「経度」という単語alwaysは名前に表示され、他の列名には表示されません。
例えば。テーブルA:
_loc_longitude_
および_loc_latitude_
そして表Bで:
_building_longitude_center
および_building_latitude_center
たとえば(+その他多数)。
トリガー機能は次のとおりです。
CREATE OR REPLACE FUNCTION make_point_with_latlon()
RETURNS trigger AS
$$
DECLARE
varlon := NULL;
varlat := NULL;
BEGIN
IF to_jsonb(NEW) SIMILAR TO '.*longitude.*' THEN
varlon := NEW.the_column_whith_longitude_in_its_name;
END IF;
IF to_jsonb(NEW) SIMILAR TO '.*latitude.*' THEN
varlat := NEW.the_column_whith_latitude_in_its_name;
END IF;
NEW.geom = ST_MakePoint(varlon, varlat);
END
$$
LANGUAGE 'plpgsql';
次のトリガーで:
CREATE TRIGGER make_point_with_latlon_but
BEFORE INSERT OR UPDATE ON schema.table1
FOR EACH ROW
EXECUTE PROCEDURE schema.make_point_with_latlon();
CREATE TRIGGER make_point_with_latlon_but
BEFORE INSERT OR UPDATE ON schema.table2
FOR EACH ROW
EXECUTE PROCEDURE schema.make_point_with_latlon();
CREATE TRIGGER make_point_with_latlon_but
BEFORE INSERT OR UPDATE ON schema.table3
FOR EACH ROW
EXECUTE PROCEDURE schema.make_point_with_latlon();
-- (...and many more other tables that need the same trigger).
パターンを検索する方法がわかりません.*latitude.*
関数に渡された列名で、そのvalueを2つの変数に入れて、ポイントを構築するために使用する方法。
そして、これらの種類のものを検索するためのグーグルスキルは完璧とはほど遠いため、ノイズの多い結果が返されます。
それを行う可能性はありますか?
INFORMATION_SCHEMAビューと特殊変数を使用できます。 TG_TABLE_SCHEMA、TG_TABLE_NAME
ドキュメントから引用:
PL/pgSQL関数がトリガーとして呼び出されると、いくつかの特殊変数がトップレベルのブロックに自動的に作成されます。彼らです:
TG_TABLE_NAME:データ型名。トリガー呼び出しを引き起こしたテーブルの名前。
TG_TABLE_SCHEMA:データ型名。トリガー呼び出しを引き起こしたテーブルのスキーマの名前。
次の例を考えてみましょう:
create table a (id int primary key, latitude int, longitude int);
create table b (id int primary key, _loc_latitude int, _loc_longitude int);
create table c (result text);
create function trg_tables()
returns trigger as
$$
declare
varlat text;
varlng text;
cmd text;
vallat int;
vallng int;
begin
varlat := (select column_name
from information_schema.columns
where table_schema = TG_TABLE_SCHEMA
and table_name = TG_TABLE_NAME
and column_name like '%latitude%');
varlng := (select column_name
from information_schema.columns
where table_schema = TG_TABLE_SCHEMA
and table_name = TG_TABLE_NAME
and column_name like '%longitude%');
execute 'select $1.' || varlat
using NEW
into vallat;
execute 'select $1.' || varlng
using NEW
into vallng;
execute format('insert into c values (''lat: '' || ''%s'' || '' lng '' || ''%s'' )',
vallat::text, vallng::text);
return NEW;
end;
$$
language plpgsql;
create trigger trg after insert on a
for each row execute procedure trg_tables();
create trigger trg after insert on b
for each row execute procedure trg_tables();
insert into a values (1,11,1);
insert into b values (1,20,2);
select * from c;
| result |
| :------------- |
| lat: 11 lng 1 |
| lat: 20 lng 2 |
db <> fiddle ここ
これは、トリガー内でのINFORMATION_SCHEMAと特殊変数の使用方法の例にすぎませんが、Postgresのプロユーザーがより良いソリューションを提供できる場合があります。