CREATE RULE

Name

CREATE RULE  --  新しいルールを定義する。

Synopsis

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

入力

name

作成するルール名。

event

イベントとは、select、 update、delete、 insert のいずれかです。

object

オブジェクトとは、 table もしくは table.column のいずれかです。

condition

任意の SQL WHERE 句であり、SQL においてインスタンス変数を 記述できる所であれば、インスタンス変数の代わりに new や old を使用す ることができます。

action

任意の SQL 文であり、SQL においてインスタンス変数を 記述できる所であれば、インスタンス変数の代わりに new や old を使用す ることができます。

出力

CREATE

ルールの作成に成功した場合に返されるメッセージ。

説明

Postgres の ルールシステム を使用して、データベー ステーブルやクラスに対する挿入、更新、削除時に実行される別の 動作を定義することができます。 現在、テーブルのビューを実装するためにルールが使用されています。

ルールにおいては、個々のインスタンスがアクセス、挿入、更新、 削除される時点では (選択、更新、削除の場合) 古いインスタンス と (挿入、更新の場合) 新しいインスタンスが存在すると想定しま す。 古いインスタンスに対して、ON 句にて指定された event と WHERE 句にて指定された condition が真と なる場合、ルールの action 部分が実 行されます。 しかし、まず、古いインスタンスと新しいインスタンスの両方、も しくは片方のフィールドの値が old.attribute-name と new.attribute-name に代入されます。

ルールの action 部分は、その起動元となったユーザコマンドと同じコマンドとトラ ンザクション識別子で実行します。

注意

SQL ルールにおいて注意しなければならないのは順番です。 同じクラス名やインスタンス変数がルールの event、 condition、 action 部分にある場合、それらは全て別のタプル変数とみなされます。 より正確にいうと、new と old だけはこれらの句の間で共有される タプル変数です。 例えば、以下の2 つの例は同じ意味を持ちます。

ON UPDATE TO emp.salary WHERE emp.name = "Joe"
    DO 
	UPDATE emp SET ... WHERE ...
    
ON UPDATE TO emp-1.salary WHERE emp-2.name = "Joe"
    DO 
	UPDATE emp-3 SET ...  WHERE ...
    
各ルールは省略可能な INSTEAD タグを持つことができます。 このタグがなければ、 action は、ルールの condition 部分において event が起こった時、ユーザコマンドに続いて実行されます。 もしあれば、 action はユーザコマンドの代わりに実行されます。 後者の場合、 action を NOTHING キーワードにすることが できます。

ルールの循環を防ぐことに注意することは非常に重要です。 例えば、次の 2 つのルール定義はどちらも Postgres で受け付けられますが、 この select コマンドにより Postgres は、問い合わせがあまりに多く循環して実行されたことが原因 となったエラーを報告します。

Example 19-1. 循環する書き換えルールの組合せの例

CREATE RULE bad_rule_combination_1 AS
    ON SELECT TO emp
    DO INSTEAD 
	SELECT TO toyemp;
     
CREATE RULE bad_rule_combination_2 AS
    ON SELECT TO toyemp
    DO INSTEAD 
	SELECT TO emp;
     

EMP から選択を行なうと、このルールにより Postgres は、問い合わせがあまり に多く循環して実行されたことが原因となったエラーを発生します。

SELECT * FROM emp;
      

あるクラスに対してルールを定義するためには、そのクラス にルール定義アクセス権限を持つ必要があります。 権限を変更する場合は、GRANT と REVOKE を使用して下さい。

SQL ルール内のオブジェクトは配列の参照 をとることができません。また、パラメータも持つことができ ません。

"oid" フィールドを除き、ルール内ではシステム属性を参照する ことはできません。 特に、これはルール内ではインスタンスの関数 (例えば foo(emp)、ここで emp はクラスです。)を呼び出すことができないことを意味しています。

ルールシステムはルールのテキストと問い合わせ計画をテキス ト属性として保持しています。 これは、ルールとその各種内部表現が 1 ページ (8KB) 程度の 何らかの値を越えた場合にルールの作成に失敗する可能性が あることを意味します。

使用法

Sam が Joe と同じ給与調整を受けるようにします。

CREATE RULE example_1 AS
    ON UPDATE emp.salary WHERE old.name = "Joe"
    DO 
	UPDATE emp 
	SET salary = new.salary
	WHERE emp.name = "Sam";
   
Joe が給与調整を受けとった時点で、このイベントが真にな り、Joe の古いインスタンスと提出された新しいインスタン スが実行処理部分で使用可能になります。 従って、彼の新しい給与は続いて実行されるルールの動作部 分に代入されます。 これにより Joe の給与は Sam に伝わります。

Bill が給与にアクセスした時に Joe の給与を参照するよう にします。

CREATE RULE example_2 AS
    ON SELECT TO EMP.salary
    WHERE old.name = "Bill"
    DO INSTEAD
	SELECT emp.salary
	FROM emp
	WHERE emp.name = "Joe";
   

Joe が靴部門の従業員の給与にアクセスできないようにし ます。 (current_user は現在のユーザ名 を返します。)

  
CREATE RULE example_3 AS
    ON 
	SELECT TO emp.salary
   	WHERE old.dept = "shoe" AND current_user = "Joe"
    DO INSTEAD NOTHING;
   

玩具部門で働く従業員というビューを作成します。

CREATE toyemp(name = char16, salary = int4);

CREATE RULE example_4 AS
    ON SELECT TO toyemp
    DO INSTEAD
    	SELECT emp.name, emp.salary
	FROM emp
        WHERE emp.dept = "toy";
   

全従業員の給与が 5000以下となるようにします。

CREATE RULE example_5 AS
    ON INERT TO emp WHERE new.salary > 5000
    DO 
	UPDATE emp SET salary = 5000
	WHERE emp.oid = new.oid;
   

互換性

SQL92

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