DOKK / manpages / debian 11 / manpages-zh / create_rule.7.zh_TW
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