[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

Name

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

Synopsis

CREATE RULE name AS ON event
    TO object [ WHERE condition ]
    DO [ INSTEAD ] action

ここで action は以下のとおりです。

NOTHING
|
query
|
( query ; query ... )
|
[ query ; query ... ]

入力

name

作成するルールの名前です。

event

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

object

オブジェクトとは、table またはtable.column のいずれかです(現時点では tableのみが実際に実装されています)。

condition

任意のブール(論理)条件式です。条件式はnewold以外のどのテーブルを参照することもできません。

query

actionを構成する単数または複数の問い合わせは、任意のSQL SELECTINSERTUPDATEDELETENOTIFY文のどれでも構いません。

conditionactionの内部では、特別なテーブル名newoldは参照されるテーブル(object)の値を参照するために使うことができます。 newはON INSERTとON UPDATEルール内で挿入または更新されている新しい行の参照に有効です。 oldは ON UPDATE、ON DELETEルールが更新、削除されている既存の行を参照するのに有効です。

出力

CREATE

ルールの作成に成功すると返されるメッセージです。

説明

PostgreSQLルールシステム によって、データベーステーブルの挿入、更新、削除の代替として行われるアクションを定義することができます。ルールはテーブルビューを実装するためにも使われます。

ルールの語義は個別のインスタンス(行)がアクセスされ、挿入、更新、削除される場合、古いインスタンス(選択、更新、削除の対象)と、新しいインスタンスが(更新と追加の対象)存在するということです。与えられたイベント型と目的のオブジェクト(テーブル)のすべてのルールは、特定されない順番で審査されます。WHERE句(存在する場合)で指定されたconditionが真である場合、そのルールの action部分が実行されます。INSTEADが指定されると、元の問い合わせの代わりに actionが行われます。そうでない場合、 ON INSERT の場合は元の問い合わせの後に、ON UPDATE や ON DELETE の場合は元の問い合わせの前に行なわれます。 conditionactionの両方のなかで、古いインスタンスあるいは新しいインスタンスの中のフィールドの値は old.attribute-namenew.attribute-name に代入されます。

ルールのaction部分は、1つ以上の問い合わせを持つことができます。複数の問い合わせを書くためには、かっこまたは大かっこ([])で囲みます。そのような問い合わせは指定された順番で実行されます(一方、オブジェクトの複数ルールの実行順番には何も保障がありません)。 actionは動作が何もないことを示すためにNOTHINGを使うこともできます。したがって、DO INSTEAD NOTHINGルールは(その条件が真の場合)元の問い合わせの実行を抑制します。DO NOTHING ルールはなにもしません。

ルールのaction部分は動作を促したユーザコマンドと同じコマンドとトランザクション識別子で実行します。

ルールとビュー

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

CREATE VIEW は(背後の格納領域が不要な)ダミーのテーブルを作成し、それに ON SELECT ルールを関連づけます。システムは、実際のテーブルがどこにあるのかを判断できないため、ビューに対する更新を許可しません。ON INSERT、ON UPDATE、ON DELETE ルール(もしくは、目的に応じてこのうちの一部)を定義して、ビューへの更新操作を他のテーブルへの適切な更新操作に置換することで、更新可能なビューという幻を作成することができます。

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

注意

テーブルにルールを定義するためには、ルール定義アクセス権を持っていなければなりません。権限を変えるにはGRANTREVOKEを使います。

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

CREATE RULE "_RETemp" AS
    ON SELECT TO emp
    DO INSTEAD 
	SELECT * FROM toyemp;

CREATE RULE "_RETtoyemp" AS
    ON SELECT TO toyemp
    DO INSTEAD 
	SELECT * FROM emp;

以下のEMPから選択しようという試みは、問い合わせが何度も循環しすぎるためにPostgreSQLにエラーを発行させます。

SELECT * FROM emp;

現在、ルールが 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 の行が存在しても、存在しなくても UPDATE 操作によりNOTIFY イベントが送信されます。これは実装上の制限であり、将来改修される可能性があります。

互換性

SQL92

CREATE RULE文はPostgreSQL言語拡張です。SQL92にはCREATE RULEはありません。