?
Dokumen ini menggunakan Manual laman web PHP Cina Lepaskan
CREATE [ OR REPLACE ] RULE name AS ON event TO table [ WHERE condition ] DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }
CREATE RULE定義一個(gè)適用于特定表或者視圖的新規(guī)則。 CREATE OR REPLACE RULE要么是創(chuàng)建一個(gè)新規(guī)則, 要么是替換一個(gè)表上的同名規(guī)則。
PostgreSQL規(guī)則系統(tǒng)允許在更新、插入、刪除 時(shí)執(zhí)行一個(gè)其它的預(yù)定義動(dòng)作。簡單的說,規(guī)則就是在指定表上執(zhí)行指定動(dòng)作 的時(shí)候,將導(dǎo)致一些額外的動(dòng)作被執(zhí)行。另外,一個(gè)INSTEAD 規(guī)則可以用另外一個(gè)命令取代特定的命令,或者令完全不執(zhí)行該命令。規(guī)則 還可以用于實(shí)現(xiàn)表視圖。規(guī)則實(shí)際上只是一個(gè)命令轉(zhuǎn)換機(jī)制,或者說命令宏。 這種轉(zhuǎn)換發(fā)生在命令開始執(zhí)行之前。如果你想要針對(duì)每個(gè)物理行獨(dú)立發(fā)生的操作, 那么可能應(yīng)該使用觸發(fā)器而不是規(guī)則。有關(guān)規(guī)則的更多信息可以在 Chapter 37找到。
目前,ON SELECT規(guī)則必須是無條件的 INSTEAD規(guī)則并且必須有一個(gè)由單獨(dú)一條 SELECT查詢組成的動(dòng)作。因此,一條 ON SELECT規(guī)則有效地把表轉(zhuǎn)成視圖,它的 可見內(nèi)容是規(guī)則的SELECT查詢返回的記錄而 不是存儲(chǔ)在表中的內(nèi)容。寫一條CREATE VIEW 命令比創(chuàng)建一個(gè)表然后在上面定義一條ON SELECT 規(guī)則的風(fēng)格要好。
你可以創(chuàng)建一個(gè)允許更新的視圖的幻覺,方法是在視圖上定義ON INSERT,ON UPDATE,ON DELETE規(guī)則 (或者滿足你需要的任何上述規(guī)則的子集),用合適的對(duì)其它表的更新替換在視圖上更新的動(dòng)作。 如果打算支持INSERT RETURNING之類,就必須確保在規(guī)則的結(jié)尾放置恰當(dāng)?shù)?tt class="LITERAL">RETURNING子句。
如果你想在視圖更新上使用條件規(guī)則,那么這里就有一個(gè)補(bǔ)充:對(duì)你希望在視圖上允許的每個(gè)動(dòng)作, 你都必須有一個(gè)無條件的INSTEAD規(guī)則。如果規(guī)則是有條件的或者它不是INSTEAD, 那么系統(tǒng)仍將拒絕執(zhí)行更新動(dòng)作,因?yàn)樗J(rèn)為最終會(huì)在視圖的虛擬表上執(zhí)行這個(gè)動(dòng)作。如果你想處理?xiàng)l件規(guī)則上的所有有用的情況, 那只需要增加一個(gè)無條件的DO INSTEAD NOTHING規(guī)則確保系統(tǒng)明白它決不會(huì)被調(diào)用來更新虛擬表就可以了。 然后把條件規(guī)則做成非INSTEAD;在這種情況下,如果它們被觸發(fā),那么它們就增加到缺省的INSTEAD NOTHING動(dòng)作中。不過這種方法目前不支持RETURNING查詢。
創(chuàng)建的規(guī)則名。它必須在同一個(gè)表上的所有規(guī)則名字中唯一。同一個(gè)表上的同一個(gè)事件類型的規(guī)則是按照字母順序運(yùn)行的。
INSERT,UPDATE, DELETE事件之一。
規(guī)則作用的表或者視圖的名字(可以有模式修飾)。
任意返回boolean的SQL條件表達(dá)式。條件表達(dá)式除了引用NEW和OLD之外不能引用任何表,并且不能有聚集函數(shù)。
指示使用該命令代替最初的命令。
ALSO指示命令應(yīng)該被執(zhí)行,除了 初始命令。 該命令應(yīng)該在最初的命令執(zhí)行之后一起執(zhí)行。
若ALSO和INSTEAD均未指定, 那么就默認(rèn)為ALSO。 如果既沒有聲明ALSO也沒有聲明 INSTEAD,那么ALSO是缺省。
命令或者彌補(bǔ)規(guī)則操作的命令。有效命令是SELECT, INSERT, UPDATE, DELETE,或者NOTIFY. 組成規(guī)則動(dòng)作的命令。有效的命令是SELECT, INSERT,UPDATE, DELETE,NOTIFY語句之一。
在condition和command里,特殊的表名字NEW和OLD可以用于指向被引用表里的數(shù)值。 NEW在ON UPDATE和ON UPDATE規(guī)則里可以指向被插入或更新的新行。OLD在ON UPDATE和ON DELETE規(guī)則里可以指向現(xiàn)存的被更新或刪除的行。 在condition和 command中,特殊表名 NEW和OLD可以用來指代所引用的 表中的值。NEW對(duì) ON INSERT和ON UPDATE規(guī)則 引用插入或更新新行是有效的, OLD對(duì)ON UPDATE 和ON DELETE規(guī)則引用更新或刪除現(xiàn)有行是有效的。
為了在表上定義或修改規(guī)則,你必須是該表的擁有者。
在視圖上用于INSERT,UPDATE,DELETE的規(guī)則中可以添加RETURNING子句基于視圖的字段返回。 如果規(guī)則被INSERT RETURNING,UPDATE RETURNING,DELETE RETURNING命令觸發(fā),這些子句將用來計(jì)算輸出結(jié)果。 如果規(guī)則被不帶RETURNING的命令觸發(fā),那么規(guī)則的RETURNING子句將被忽略。目前僅允許無條件的 INSTEAD 規(guī)則包含 RETURNING 子句, 而且在同一個(gè)事件內(nèi)的所有規(guī)則中最多只能有一個(gè) RETURNING 子句。這樣就確保只有一個(gè)RETURNING子句可以用于計(jì)算結(jié)果。 如果在任何有效規(guī)則中都不存在RETURNING子句,該視圖上的RETURNING查詢將被拒絕。
有一件很重要的事情是要避免循環(huán)規(guī)則。比如,盡管下面兩條規(guī)則定義都是PostgreSQL可以接受的, 但其中的一條SELECT命令會(huì)導(dǎo)致PostgreSQL報(bào)告一條錯(cuò)誤信息,因?yàn)樵摬樵冄h(huán)了太多次:
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;
目前,如果一個(gè)規(guī)則包含一個(gè)NOTIFY命令,那么該NOTIFY命令將被無條件執(zhí)行, 也就是說,即使規(guī)則不施加到任何行上面,該NOTIFY也會(huì)被執(zhí)行。比如,在:
CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable; UPDATE mytable SET name = 'foo' WHERE id = 42;
里,一個(gè)NOTIFY事件將在UPDATE的時(shí)候發(fā)出, 不管是否有滿足id = 42條件的行。 這是一個(gè)實(shí)現(xiàn)的限制,將來的版本應(yīng)該修補(bǔ)這個(gè)毛病。
CREATE RULE是PostgreSQL語言的擴(kuò)展, 整個(gè)規(guī)則重寫系統(tǒng)都是如此。