1

いくつかのテーブルで機能し、渡されたパラメーターに基づいて結果を組み立てる関数を PostgreSQL で作成しました。これは非常にうまく機能し、クライアントの観点からは、パラメータが追加された通常のテーブルのように見えます (つまり、通常の選択クエリのようにクエリを実行できます)。

基になるデータに関する情報を隠し続けるために、テーブルに書き込む方法も作成したいと思います。基本的に関連する基になるテーブルを更新する関数を実行するトリガーを作成すると思いました。ただし、関数でトリガーを作成できませんでした。テーブル以外にトリガーを作成する方法はありますか? ビューの使用も検討していましたが(ビューにトリガーを作成できると信じているため)、関数を変更して、渡すことができないため、適していないビューにする必要がありますパラメータ。

4

1 に答える 1

3

更新可能なビューに相当するものを、可能な場合は関数または関数で作成したいと考えているINSERTようUPDATEですDELETE。これは不可能です。

関数のようなインターフェイスを提供する場合は、データ変更用の関数も提供します。

または、関数をビューに変換します。WHEREパラメータを関数に渡す代わりに、句を使用してビューを制限できるようにします。次に、ビュー トリガー (PostgreSQL 9.1 以降) またはルール (PostgreSQL 9.0 以降。可能であれば新しいバージョンでは使用しないでください) を使用して、ビューで を有効INSERTUPDATEDELETEます。CREATE TRIGGERおよびを参照してくださいCREATE RULE。ルールは扱いにくいので、お好みでビュー トリガーを使用してください。

PostgreSQL はフィルターをビューにプッシュすることに関して非常に巧妙であるため、SELECT * FROM some_view WHERE some_col = 4通常、ビュー全体をスキャンしてフィルター処理することはありません。WHERE句をビューのクエリに「プッシュ」して実行します。したがって、ビューがSELECT * FROM some_table WHERE NOT is_archivedPostgreSQL の場合、実際には と同等の実行が開始されSELECT * FROM some_table WHERE (NOT is_archived) AND some_col = 4ます。このため、ほんの数行とすべての行のビューに対してクエリを実行すると、完全に異なるクエリ プランが得られることがよくあります。少し前に書いた投稿に、この例があります。

ビューで関数をラップするだけでは、それが SQL 関数でSTABLEあり、インライン化できない場合を除き、うまく機能しませんIMMUTABLE(したがって、インライン化できます)。関数自体に基づいてビューを作成するのではなく、関数から SQL を抽出し、同じ SQL に基づいてビューを作成することをお勧めします。

関数のパラメーターが単純なWHERE句で使用されていない場合、関数のようにパラメーターをビューに渡す方法がないため、より複雑になります。パラメータのすべての可能な値のビューを作成し、それをフィルタリングすることはできますが、Pg がビューを seq-scan すると、本当にひどいパフォーマンスにつながる可能性があります。これらのより複雑なケースでは、変更を行うための関数呼び出しインターフェイスを提供したいと考えています。

于 2012-10-29T01:22:59.493 に答える