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


22

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

現在、新しいレプリカを設定した後、更新を実行し、値をそれ自体に設定して(たとえば、UPDATE tablename SET field=field)トリガーを強制的に実行しますが、一部のテーブルは数百万のレコードであり、成長し、30分かかることがあります。(そして、真空もあります)。

それをトリガーするより良い方法、または渡された入力またはNEW呼び出しコンテキストに依存する入力で機能するような関数を書く方法はありますか?1つが更新され、もう1つが更新されないことを何度も見てきたため、2つの異なる機能を保持することに消極的です。


トリガーを実行する方法を知っていました... 良い方法があるかどうか尋ねました。
ジョー

回答:


19

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

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();

Doh ...私はそれについて逆向きに考えていました(トリガー関数をvisa-versaではなく、プロシージャによって呼び出し可能にしようとしています)。
ジョー

1
実際に行ったとき、「行」は予約語であることに気づいたので、他の人が長いデバッグを費やさないように例を修正しました。
ジョー

1
私は本当に数年前にフォローすべきだった。私のシステムですべてを機能させるまでにしばらく時間がかかりました...そしてこの方法は機能しますが、パフォーマンスはひどいものでした。(30分から1日以上かけて完了しました)。
ジョー14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.