PostgreSQL 8.0.0 文書
前のページ | 巻戻し |  | 早送り | 次のページ

# CREATE RULE

## 名前

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

## 概要

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

## 説明

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

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

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

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

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

## パラメータ

`name`

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

`event`

  イベントとは、`SELECT`、`INSERT`、`UPDATE`、`DELETE`のいずれかです。

`table`

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

`condition`

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

`INSTEAD`

  `INSTEAD`は、元のコマンドの代わりにこのコマンドが実行されることを示します。

`ALSO`

  `ALSO`は元のコマンドに加えてこのコマンドが実行されることを示します。

  `ALSO`も`INSTEAD`も指定されなかった場合、`ALSO`がデフォルトです。

`command`

  ルールのアクションを構成する単一または複数のコマンドです。 有効なコマンドは`SELECT`、`INSERT`、`UPDATE`、`DELETE`、`NOTIFY`文です。

`condition`と`command`の内部では、参照されるテーブルの値を参照するために、特別なテーブル名`NEW`と`OLD`を使用できます。 `NEW`は、`ON INSERT`と`ON UPDATE`ルールで、挿入または更新されている新しい行を参照するのに有効です。 `OLD`は、`ON UPDATE`と`ON 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 ALSO NOTIFY mytable;

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

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

## 互換性

問い合わせ書き換えシステム全体同様、`CREATE RULE`はPostgreSQLの言語拡張です。

前のページ | ホーム | 次のページ
CREATE OPERATOR CLASS | 上に戻る | CREATE SCHEMA