web-dev-qa-db-ja.com

%current%テーブルから選択するPostgreSQLトリガー関数

同じ列名を持つ複数のテーブルがあり、次のように列の値が異なるだけです。

tbl_log_a
tbl_log_b
tbl_log_c
...

aからzまでの26のテーブル。各テーブルには、まったく同じことを行うトリガー関数を呼び出すトリガーがあります。

SELECT columnname FROM tbl_log_a

それ以外は、すべてのトリガー関数がまったく同じことを行います。それらは以下の点で異なります。

select columnname FROM tbl_log_a
select columnname FROM tbl_log_b
select columnname FROM tbl_log_c
...

そのため、tbl_log_%letter%ごとに1つずつ、26個のトリガー関数を作成する必要があります。トリガー関数に次のことを伝える方法はありますか?

SELECT columnname FROM %currenttable%

%currenttable%とは、トリガーが配置されているテーブルを意味します。または:

SELECT columnname FROM tbl_log_%letter%

Postgres 9.1で可能ですか?動的に決定されるテーブルについて読んでいます。どんな手掛かり?トリガー関数はそのテーブル内の複数の列で機能するため、テーブル名自体をそのテーブル内の列ではなく変数内に格納したいと思います。

TG_TABLE_NAME
TG_TABLE_SCHEMA
4
Natysiu16

トリガー引数を使用することをお勧めしましたが、実際には必要ありません。 自動変数 _TG_TABLE_SCHEMA_および_TG_TABLE_NAME_を使用するか、_TG_RELID_を使用できます。これらは、動的SQLのEXECUTEと一緒に、必要なことを実行できます。

_BEGIN
    EXECUTE format('SELECT colname FROM %I', TG_RELID)
END;
_

または

_BEGIN
    EXECUTE format('SELECT colname FROM %I.%I', TG_TABLE_SCHEMA, TG_TABLE_NAME)
END;
_

(もちろん、SELECTにはデータの宛先がないため、これらはそのままでは機能しません。EXECUTE format(..) INTO ...を使用して結果をDECLAREdに保存する必要があります変数)、例えば.

_DECLARE
    _colvar integer;
BEGIN
    EXECUTE format('SELECT colname FROM %I.%I', TG_TABLE_SCHEMA, TG_TABLE_NAME) INTO _colvar;
    RAISE NOTICE 'colname value was %',_colvar;
END;
_
5
Craig Ringer

架空のSELECT columnname FROM %currenttable%に対応する実際の構文は、plpgsqlでは次のようになります。

execute format('SELECT columnname FROM %I.%I',
                TG_TABLE_SCHEMA, TG_TABLE_NAME);

TG_ *組み込み変数は トリガープロシージャ および 基本ステートメントexecuteおよびformat plpgsqlコンストラクトに記載されています。

上記のクエリは、それ自体が不合理です(どこにも行かない結果を選択します)。その目的は、実際のクエリを構築できる基本的な構文を示すことです。

2
Daniel Vérité

または、TG_RELIDを使用できますが、そのデータ型はoidではなくプレーンregclassであるため、スキーマ修飾された自動変換(現在のsearch_pathで必要な場合のみ)を使用するには、明示的にregclassにキャストして、テーブル名を正しくエスケープする必要があります。 ドキュメント:

TG_RELID

データ型oid;トリガー呼び出しを引き起こしたテーブルのオブジェクトID。

大胆な強調鉱山。そもそもなぜregclassにしなかったのか...

EXECUTE format('SELECT columnname FROM %s', TG_RELID::regclass);

そして、あなたが結果で何をしているのかはまだ不明です。通常、これをINSERT/UPDATE/DELETEステートメントで使用するか、 結果を変数に書き込みます

EXECUTE format('SELECT columnname FROM %s', TG_RELID::regclass)
INTO my_variable;

最初の値のみが割り当てられます。 SELECTがさらに行を見つけると、残りは破棄されます。 ORDER BY ... LIMIT 1を追加することもできます。

関連:

2