CREATE RULE(7) SQL Commands CREATE RULE(7)

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規則系統允許我們在從資料庫或表中更新, 插入或刪除東西時定義一個其它的動作來執行。 簡單說,規則就是當我們在指定的表上執行指定的動作的時候,導致一些額外的動作被執行。 另外,規則可以用另外一個命令取代某個特定的命令,或者令命令完全不被執行。 規則還用於實現表檢視。我們要明白的是規則實際上只是一個命令轉換機制,或者說命令宏。 這種轉換髮生在命令開始執行之前。如果你實際上想要一個為每個物理行獨立發生的操作, 那麼你可能還是要用一個觸發器,而不是規則。有關規則的更多資訊可以在 ``The Rule System'' 找到。


目前,ON SELECT 規則必須是無條件的 INSTEAD 規則並且必須有一個由一條 SELECT 查詢組成的動作。 因此,一條 ON SELECT 規則有效地把物件錶轉成檢視, 它的可見內容是規則的 SELECT 查詢返回的記錄而不是儲存在表中的內容(如果有的話)。 我們認為寫一條 CREATE VIEW 命令比建立一個表然後定義一條 ON SELECT 規則在上面的風格要好。


你可以建立一個可以更新的檢視的幻覺, 方法是在檢視上定義 ON INSERT,ON UPDATE,和 ON DELETE 規則(或者滿足你需要的任何上述規則的子集),用合適的對其它表的更新替換在檢視上更新的動作。


如果你想在檢視更新上使用條件規則,那麼這裡就有一個補充: 對你希望在檢視上允許的每個動作,你都必須有一個無條件的 INSTEAD 規則。 如果規則是有條件的,或者它不是 INSTEAD, 那麼系統仍將拒絕執行更新動作的企圖,因為它認為它最終會在某種程度上在虛擬表上執行動作。 如果你想處理條件規則上的所由有用的情況,那也可以;只需要增加一個無條件的 DO INSTEAD NOTHING 規則確保系統明白它將決不會被呼叫來更新虛擬表就可以了。 然後把條件規則做成非 INSTEAD;在這種情況下,如果它們被觸發,那麼它們就增加到預設的 INSTEAD NOTHING 動作中。


建立的規則名。它必須在同一個表上的所有規則的名字中唯一。 同一個表上的同一個事件型別的規則是按照字母順序執行的。

事件是 SELECT, UPDATE,DELETE 或 INSERT 之一。

規則施用的表或者檢視的名字(可以有模式修飾)。

任意 SQL 條件表示式(返回 boolean)。 條件表示式除了引用 NEW 和 OLD 之外不能引用任何表,並且不能有聚集函式。

組成規則動作的命令。有效的命令是 SELECT,INSERT, UPDATE,DELETE,或 NOTIFY 語句之一。


在 condition 和 command 裡, 特殊表名字 NEW 和 OLD 可以用於指向被引用表裡的數值 new 在 ON INSERT 和 ON UPDATE 規則裡可以指向被插入或更新的新行。 OLD 在 ON UPDATE,和 ON DELETE 規則裡可以指向現存的被更新,或者刪除的行。


為了在表上定義規則,你必須有 RULE 許可權。


有一件很重要的事情是要避免迴圈規則。 比如,儘管下面兩條規則定義都是 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;
裡,一個 NOTIFY 事件將在 UPDATE 的時候發出,不管是否有某行的 id = 42。這是一個實現的限制,將來的版本應該修補這個毛病。

CREATE RULE 是 PostgreSQL 語言的擴充套件,整個規則系統也是如此。

譯者

Postgresql 中文網站 何偉平 <laser@pgsqldb.org>

本頁面中文版由中文 man 手冊頁計劃提供。
中文 man 手冊頁計劃:https://github.com/man-pages-zh/manpages-zh

2003-11-02 SQL - Language Statements