[11/15開催: PostgreSQL Conference Japan 2019 参加受付中] 
他のバージョンの文書 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

CREATE RULE

名前

CREATE RULE -- 新しい書き換えルールの定義

概要

CREATE [ OR REPLACE ] RULE name AS ON event
    TO table [ WHERE condition ]
    DO [ INSTEAD ] { NOTHING | command | ( command ; command ... ) }

説明

CREATE RULE により、指定したテーブルまたはビューに適用するルールを新しく定義できます。 CREATE OR REPLACE RULE を使用すると、ルールを新しく作成するか、同じテーブルの同じ名前の既存ルールを置き換えるかのいずれかを実行します。

PostgreSQLのルールシステムによって、データベーステーブルの挿入、更新、削除の代替として行われるアクションを定義することができます。 大雑把にいうと、指定されたテーブルに指定されたコマンドが実行された時に、ルールによって実行されるコマンドが追加されます。 その他にも、ルールによって、指定されたコマンドを他のコマンドに置き換えることも、まったくコマンドを実行させないようにすることも可能です。 ルールはテーブルビューを実装するためにも使われます。 ルールは本当にコマンドを変換する機構、もしくは、コマンドマクロであることを認識することが重要です。 この変換はコマンドの実行が始まる前に発生します。 実際に各物理行に独立した操作を行いたい場合、おそらくルールではなくトリガを使用することでしょう。 ルールシステムについてのより詳細は、第34章 に記載されています。

現時点では、ON SELECTルールは無条件のINSTEADルールでなければならず、単一SELECTコマンドで成り立つアクションを持っていなければなりません。 このようにして、ON SELECT ルールはテーブルを効果的にビューに変え、そのビューの可視的な内容は (もしあったとしても) テーブル内に格納されているものではなく、ルールの SELECT コマンドによって返された行です。 実際のテーブルを作成しそれにON SELECTルールを定義するよりは CREATE VIEWコマンドを書く方がよい形式とされています。

ON INSERTON UPDATEON DELETE ルール(もしくは、目的に応じてこのうちの一部)を定義して、ビューへの更新操作を他のテーブルへの適切な更新操作に置換することで、更新可能なビューという幻を作成することができます。

ビューの更新の際に条件付きルールの使用を予定している場合、罠があります。 そのビューに許可したい操作それぞれに無条件 INSTEAD ルールを用意する 必要があることです。 ルールが条件付き、または、INSTEAD ではない場合、システムは更新操作の試行を拒絶します。 その場合、ある条件でビューのダミーテーブルへの操作を行なうことになるとシステムがみなすからです。 条件付きルール内で全ての使用し得るケースを扱うのであれば、無条件の DO INSTEAD NOTHING ルールを追加し、システムにダミーテーブルへの更新を行なうことが決してないことを理解させることで、それを実現することができます。 さらに、INSTEAD でない条件付きルールを作成します。 これらが起動される条件では、デフォルトのINSTEAD NOTHING 動作に追加されます。

パラメータ

name

作成するルールの名前です。 この名前は、同じテーブルの他のルールとは異なる名前にする必要があります。 複数の同一テーブル、同一イベント種類のルールがあった場合、その名前のアルファベット順で適用されます。

event

イベントとは、SELECTINSERTUPDATEDELETEのいずれかです。

table

ルールを適用するテーブルまたはビューの名前です (スキーマ修飾名でも可)。

condition

任意の SQL 条件式です (boolean 型を返します)。 条件式では、new および old 以外は、どのテーブルも参照できません。 また、集約関数を含めることもできません。

command

ルールのアクションを構成する単数または複数のコマンドです。 有効なコマンドは SELECTINSERTUPDATEDELETENOTIFY文です。

conditioncommand の内部では、特別なテーブル名 NEWOLD は参照されるテーブルの値を参照するために使用できます。 NEW は、ON INSERTON UPDATE ルールで、挿入または更新されている新しい行を参照するのに有効です。 OLD は、ON UPDATEON DELETE ルールで、更新または削除されている既存の行を参照するのに有効です。

注釈

テーブルにルールを定義するためには RULE 権限が必要です。

循環ルールを避けるために注意を払うことはとても重要です。 たとえば、下記の2つのルールそれぞれがPostgreSQLに受け入れられた場合、SELECTコマンドは、問い合わせが何度も循環しすぎたためにPostgreSQLにエラーを表示させます。

CREATE RULE "_RETURN" AS
    ON SELECT TO t1
    DO INSTEAD 
	SELECT * FROM t2;

CREATE RULE "_RETURN" AS
    ON SELECT TO t2
    DO INSTEAD 
	SELECT * FROM t1;

SELECT * FROM t1;

現在、ルールが NOTIFY 問い合わせを含む場合、NOTIFY は無条件に実行されます。 つまり、ルールを適用すべき行が存在しなかったとしても、NOTIFY は発行されます。 例えば、

CREATE RULE notify_me AS ON UPDATE TO mytable DO NOTIFY mytable;

UPDATE mytable SET name = 'foo' WHERE id = 42;

では、id = 42を持つ行があってもなくても、1つのNOTIFYイベントがUPDATEの際に送信されます。 これは実装上の制限であり、将来のリリースでは修正されるかもしれません。

互換性

ルールシステム全体同様、CREATE RULEPostgreSQL の言語拡張です。