PostgreSQL 9.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`ルールによって指定されたコマンドを他のコマンドに置き換えたり、まったくコマンドを実行しないようにすることも可能です。 また、ルールはテーブルビューを実装するためにも使われます。 重要なのは、ルールとは実際にコマンドを変換する仕組み、言い換えれば、コマンドのマクロであることです。 ルールによる変換はコマンドの実行前に発生します。 各物理行を個別に操作したい場合、ルールではなくトリガを使用する方が良いでしょう。 ルールシステムについての詳細は、第37章に記載されています。

現時点では、`ON SELECT`ルールは、条件を持たない`INSTEAD`ルールでなければなりません。また、`ON SELECT`ルールが持つアクションは、単独の`SELECT`コマンドのみで構成される必要があります。 したがって、`ON SELECT`ルールを使えば、効率的にテーブルをビューにすることができます。このビューでは、元のテーブルの内容ではなく、ルールに含まれる`SELECT`コマンドが返す行が、ビューの内容として提示されます。 ただし、テーブル自体を作成し、それに`ON SELECT`ルールを定義するよりは、`CREATE VIEW`コマンドを使用する方をお勧めします。

`ON INSERT`、`ON UPDATE`、`ON DELETE`ルールを必要に応じて定義し、ビューに対する更新操作を他のテーブルに対する適切な更新操作に置換することで、更新可能なビューという実在しないオブジェクトを作成することができます。 `INSERT RETURNING`などをサポートしたければ、これらのルールに適切な`RETURNING`句を確実につけてください。

ビューの更新に条件付きルールを使用しようとする場合、落とし穴があります。 そのビューに許可するそれぞれの操作に、条件を持たない`INSTEAD`ルールを用意する必要があることです。 ルールが条件付きであったり、`INSTEAD`でない場合、システムは更新操作を拒否します。 その場合、システムが、場合によっては、ビューのダミーテーブルに対する操作になる可能性があるとみなすからです。 使用する全てのケースについて条件付きルールを作成する場合は、条件を持たない`DO INSTEAD NOTHING`ルールを追加し、ダミーテーブルに対する更新は呼び出されないことをシステムに明示します。さらに、条件付きルールには、`INSTEAD`と指定しないようにします。 これらの条件が満たされた場合、デフォルトの`INSTEAD NOTHING`アクションにルールに含まれるアクションが追加されます。 （しかし現在、この方法では`RETURNING`問い合わせのサポートがうまく動作しません。）

## パラメータ

`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`ルールで有効です。更新または削除される既存の行を参照します。

## 注釈

テーブルにルールを定義する、または、そのルールを変更するためには所有者でなければなりません。

ビュー上の`INSERT`、`UPDATE`、`DELETE`ルールでは、`RETURNING`句を追加して、ビューの列を返すことができます。 ルールが`INSERT RETURNING`、`UPDATE RETURNING`、`DELETE RETURNING`コマンドによって呼び出された場合、この句は出力を計算することに使用されます。 `RETURNING`なしでルールが呼び出された場合、ルールの`RETURNING`句は無視されます。 現在の実装では、無条件の`INSTEAD`ルールのみが`RETURNING`を含むことができます。 さらに、同一イベント用のすべてのルールの中で多くても1つの`RETURNING`句を持つことができます。 （これにより確実に、結果を計算するために使用される`RETURNING`句の候補が1つのみになります。） ビュー上の`RETURNING`問い合わせは、利用可能なルールすべてで`RETURNING`が存在しない場合に拒絶されます。

ルールの循環は絶対に避けるよう注意してください。 例えば、下記の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`という条件に一致する行があってもなくても、`UPDATE`の際、1つの`NOTIFY`イベントが送信されます。 これは実装上の制限であり、将来のリリースでは修正されるかもしれません。

## 互換性

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

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