支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3

38.1. 事件觸發器的行為概述 #

當與事件觸發器相關聯的事件發生在定義它的資料庫中時,就會觸發該事件觸發器。目前,唯一支援的事件是 loginddl_command_startddl_command_endtable_rewritesql_drop。未來版本可能會增加對其他事件的支援。

login 事件發生在經過身份驗證的使用者登入系統時。此事件的觸發程序中的任何錯誤都可能阻止成功登入系統。可以透過在連線字串或組態檔中將 event_triggers 設定為 false 來解決這些錯誤。或者,您可以以單一使用者模式重新啟動系統(因為事件觸發器在此模式下已停用)。有關使用單一使用者模式的詳細資訊,請參閱 postgres 參考頁面。login 事件也會在備用伺服器上觸發。為了防止伺服器無法存取,此類觸發器在備用伺服器上執行時必須避免將任何內容寫入資料庫。此外,建議避免在 login 事件觸發器中執行長時間執行的查詢。請注意,例如,在 psql 中取消連線不會取消正在進行的 login 觸發器。

ddl_command_start 事件發生在執行 CREATEALTERDROPSECURITY LABELCOMMENTGRANTREVOKE 命令之前。在觸發事件觸發器之前,不會檢查受影響的物件是否存在。但是,作為例外,此事件不會針對以共享物件(資料庫、角色和表空間)為目標的 DDL 命令,或針對以事件觸發器本身為目標的命令發生。事件觸發器機制不支援這些物件類型。ddl_command_start 也發生在執行 SELECT INTO 命令之前,因為這相當於 CREATE TABLE AS

ddl_command_end 事件發生在執行同一組命令之後。要取得更多關於DDL操作的詳細資訊,請使用 ddl_command_end 事件觸發器程式碼中的傳回集合函式 pg_event_trigger_ddl_commands()(請參閱 第 9.30 節)。請注意,觸發器在動作發生後(但在交易提交之前)觸發,因此可以讀取已變更的系統目錄。

對於任何刪除資料庫物件的操作,sql_drop 事件會在 ddl_command_end 事件觸發器之前觸發。要列出已刪除的物件,請使用 sql_drop 事件觸發器程式碼中的傳回集合函式 pg_event_trigger_dropped_objects()(請參閱 第 9.30 節)。請注意,觸發器在從系統目錄中刪除物件後執行,因此無法再查找它們。

table_rewrite 事件發生在 ALTER TABLEALTER TYPE 命令的某些動作重新編寫表之前。雖然有其他控制語句可用於重新編寫表,例如 CLUSTERVACUUM,但 table_rewrite 事件不會被它們觸發。要找到被重新編寫的表的 OID,請使用函式 pg_event_trigger_table_rewrite_oid() (請參閱 第 9.30 節)。要找出重新編寫的原因,請使用函式 pg_event_trigger_table_rewrite_reason()

事件觸發器(與其他函式一樣)無法在中止的交易中執行。因此,如果 DDL 命令因錯誤而失敗,則任何相關聯的 ddl_command_end 觸發器都不會執行。相反地,如果 ddl_command_start 觸發器因錯誤而失敗,則不會觸發任何進一步的事件觸發器,並且不會嘗試執行命令本身。同樣地,如果 ddl_command_end 觸發器因錯誤而失敗,DDL 語句的效果將會回滾,就像包含交易中止的任何其他情況一樣。

有關事件觸發器機制支援的完整命令列表,請參閱 第 38.2 節

事件觸發器是使用命令 CREATE EVENT TRIGGER 建立的。為了建立事件觸發器,您必須先建立一個具有特殊回傳類型 event_trigger 的函式。此函式不需要(也可能無法)傳回值;回傳類型僅作為函式將被呼叫為事件觸發器的訊號。

如果為特定事件定義了多個事件觸發器,它們將按觸發器名稱的字母順序觸發。

觸發程序定義也能指定一個 WHEN 條件,例如,ddl_command_start 觸發程序可以只針對使用者想要攔截的特定指令觸發。這種觸發程序的常見用途是限制使用者可以執行的 DDL 操作範圍。

提交更正

如果您在文件中看到任何不正確、與您使用特定功能時的體驗不符,或需要進一步說明的內容,請使用此表單來報告文件問題。