1. 程式人生 > >PostgreSQL中的事件觸發器

PostgreSQL中的事件觸發器

PostgreSQL也提供了事件觸發器。和常規觸發器(在一個表上並且只捕捉 DML 事件)不同,事件觸發器對一個特定資料庫來說是全域性的,並且可以捕捉 DDL 事件。

只要與一個事件觸發器相關的事件在事件觸發器所在的資料庫中發生, 該事件觸發器就會被引發。當前支援的事件是 ddl_command_startddl_command_end table_rewritesql_drop

ddl_command_start事件在CREATE、 ALTER、DROP、SECURITY LABEL、 COMMENT、GRANT或者REVOKE 命令執行之前發生。在事件觸發器引發前不會做受影響物件是否存在的檢查。不過,有一個例外情況是,這個事件不會為目標是共享物件 (資料庫、角色 以及表空間) 的 DDL 命令發生,也不會為目標是事件觸發器的 DDL 命令發生。ddl_command_start也會在SELECT INTO 命令的執行之前發生,因為這等價於 CREATE TABLE AS。

ddl_command_end事件在同一組命令的執行之後發生。為了獲取發生的DDL操作的更多細節,可以從 ddl_command_end事件觸發器程式碼中使用集合返回函式 pg_event_trigger_ddl_commands()。注意該觸發器是在動作已經發生之後(但是在事務提交前)引發,因此係統目錄會被讀作已更改。

sql_drop事件為任何刪除資料庫物件的操作在 ddl_command_end事件觸發器之前發生。要列出已經被刪除的物件,可以從sql_drop事件觸發器程式碼中使用集合返回函式 pg_event_trigger_dropped_objects()。注意該觸發器是在物件已經從系統目錄刪除以後執行,因此不能再檢視它們。

table_rewrite事件在表被命令ALTER TABLE和 ALTER TYPE的某些動作重寫之前發生。雖然其他控制語句(例如 CLUSTER和VACUUM)也可以用來重寫表,但是它們不會觸發table_rewrite事件。

不能在一箇中止的事務中執行事件觸發器。因此,如果一個 DDL 命令出現錯誤失敗,將不會執行任何相關的ddl_command_end觸發器。相反,如果一個ddl_command_start觸發器出現錯誤失敗,將不會引發進一步的事件觸發器,並且不會嘗試執行該命令本身。類似地,如果一個ddl_command_end觸發器出現錯誤失敗,DDL 命令的效果將被回滾。

事件觸發器通過命令CREATE EVENT TRIGGER建立。為了建立一個事件觸發器,你必須首先建立一個有特殊返回型別 event_trigger的函式。這個函式不一定需要一個返回值, 該返回型別僅僅是作為一種訊號表示該函式要被作為一個事件觸發器呼叫。

如果對於一個特定的事件定義了多於一個事件觸發器,它們將按照觸發器名稱的字母表順序被引發。

一個觸發器定義也可以指定一個WHEN條件,這樣事件觸發器(例如ddl_command_start觸發器)就可以只對使用者希望介入的特定命令觸發。這類觸發器的通常用法是用於限制使用者可能執行的 DDL 操作的範圍。

 

By Kalath