| PostgreSQL 7.4 文檔 | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Fast Forward | Next | |
本章描述如何書寫觸發器函數。 觸發器函數可以用 C 或者任何其它可用的過程語言編寫。 目前不可能用 SQL 語言書寫觸發器。
一個觸發器函數可以再一個INSERT,UPDATE, 或者 DELETE 命令之前或者之後執行,要麼是對每個被修改的行一次, 要麼是每條 SQL 一次。 如果發生觸發器事件,那麼將在合適的時刻調用觸發器的函數以處理該事件。
觸發器函數必須在創建觸發器之前,作為一個沒有參數並且返回trigger類型的函數定義。 (觸發器函數通過特殊的 TriggerData 結構接收其輸入,而不是用普通函數參數那種形式。)
一旦創建了一個合適的觸發器函數,觸發器就用 CREATE TRIGGER 創建。同一個觸發器函數可以用于多個觸發器。
觸發器函數給調用它的執行者返回一表數據行(一個類型為 HeapTuple 的數值), 那些在操作之前觸發的觸發器有以下選擇:
它可以返回NULL以忽略對當前行的操作(這樣該行就將不會被插入/更新/刪除)。
只用于INSERT和UPDATE觸發器: 返回的行將成為被插入的行或者是成為將要更新的行。 這樣就允許觸發器函數修改被插入或者更新的行。
一個無意導致任何這類行為的在操作之前觸發的觸發器必須仔細返回那個被當作新行傳進來的同一行 (也就是說,對于 INSERT 和 UPDATE 觸發器而言,是 NEW 行, 對于 DELETE 觸發器而言,是 OLD 行)。
對于在操作之後出發的觸發器,其返回值會被忽略,因此他們可以返回NULL。
如果多于一個觸發器為同樣的事件定義在同樣的關系上, 觸發器將按照由名字的字母順序排序的順序觸發。 如果是事件之前觸發的觸發器,每個觸發器返回的可能已經被修改過的行成為下一個觸發器的輸入。 如果任何事件之前觸發的觸發器返回 NULL 指針, 那麼其操作被丟棄並且隨後的觸發器不會被觸發。
如果一個觸發器函數執行 SQL 命令,然後這些命令可能再次觸發觸發器。 這就是所謂的級聯觸發器。對級聯觸發器的級聯深度沒有明確的限制。 有可能出現級聯觸發器導致同一個觸發器的遞歸調用的情況; 比如,一個 INSERT 觸發器可能執行一個命令, 把一個額外的行插入同一個表中,導致 INSERT 觸發器再次激發。 避免這樣的無窮遞歸的問題是觸發器程序員的責任。
在定義一個觸發器的時候,我們可以聲明一些參數。 在觸發器定義裡面包含參數的目的是允許類似需求的不同觸發器調用同一個函數。 比如,我們可能有一個通用的觸發器函數, 接受兩個字段名字,把當前用戶放在第一個,而當前時間戳在第二個。 只要我們寫得恰當,那麼這個觸發器函數就可以和觸發它的特定表無關。 這樣同一個函數就可以用于有著合適字段的任何表的 INSERT 事件,實現自動跟蹤交易表中的記錄創建之類的問題。如果定義成一個 UPDATE 觸發器,我們還可以用它跟蹤最後更新的事件。