web-dev-qa-db-ja.com

列名に「Word」が存在する場合、トリガー関数でvar = "NEW.this_Word_column"を設定します

環境

PostgreSQL 10.12を使用しています。

地理データを含む特定のテーブルでトリガー関数を起動できるようにしたい。

このトリガー関数は、geomlatの値から列lonPotGIS ポイントを作成するように設計されています。
新しい行が挿入されるたびに、これと同じトリガー関数を複数のテーブルに適用したいと思います。
緯度と経度の値を保持する列の名前はテーブル間で一貫していませんが、パターンに従います...

私が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つの変数に入れて、ポイントを構築するために使用する方法。
そして、これらの種類のものを検索するためのグーグルスキルは完璧とはほど遠いため、ノイズの多い結果が返されます。

質問

それを行う可能性はありますか?

1
s.k

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のプロユーザーがより良いソリューションを提供できる場合があります。

2
McNets