支援的版本:目前版本 (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 操作範圍。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能時的經驗不符或需要進一步澄清的地方,請使用此表單來回報文件問題。