web-dev-qa-db-ja.com

postgresテーブルの各レコードに対してトリガーを実行する良い方法はありますか?

一部のテーブル(Slony-Iを介して複製)のデザインを制御できないシステムがあるため、「シャドウテーブル」と呼ばれる一連のものがあり、複製されたテーブルからいくつかの情報を抽出します、それを必要な処理済みの形式で保存し、無視したいレコードは削除します。

現在、新しいレプリカを設定した後、更新を実行して値を元に戻しました(例:UPDATE tablename SET field=field)トリガーを強制的に実行しますが、一部のテーブルは数百万のレコードであり、増大しており、30分かかる場合があります。 (そして、真空もある)。

それをトリガーするより良い方法、または呼び出しコンテキストに応じて渡された入力またはNEWのいずれかで機能するように関数を作成する方法はありますか?片方が更新され、もう片方が更新されないところを何度も目にしているため、2つの異なる関数を保持することに抵抗があります。

23
Joe

これは、次のテンプレートを使用して実行できます。

CREATE TABLE tablename ( ... );

/* for direct invocation */
CREATE FUNCTION propagate_data(newrow tablename) RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO other_table VALUES (newrow.a, newrow.b, ...);
END:
$$;

/* trigger function wrapper */
CREATE FUNCTION propagate_data_trg() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    PERFORM propagate_data(NEW);
END;
$$;

CREATE TRIGGER propagate_data AFTER INSERT ON tablename FOR EACH ROW
    EXECUTE PROCEDURE propagate_data_trg();
19