Postgres trigger after insert accessing NEW

前端 未结 1 1023
夕颜
夕颜 2020-12-09 08:21

I have a pretty simple trigger:

CREATE OR REPLACE FUNCTION f_log_datei()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO logs (aktion, tabelle, benutzer_id) VALUES         


        
相关标签:
1条回答
  • 2020-12-09 09:04

    From the fine manual:

    36.1. Overview of Trigger Behavior
    [...]
    For a row-level trigger, the input data also includes the NEW row for INSERT and UPDATE triggers, and/or the OLD row for UPDATE and DELETE triggers. Statement-level triggers do not currently have any way to examine the individual row(s) modified by the statement.

    And from Trigger Procedures:

    NEW
    Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level triggers. This variable is NULL in statement-level triggers and for DELETE operations.

    Note what it says about row-level triggers and statement-level triggers.

    You have a statement-level trigger:

    ...
    FOR EACH STATEMENT
    EXECUTE PROCEDURE f_log_datei();
    

    Statement-level triggers are triggered once per statement and a statement can apply to multiple rows so the notion of affected row (which is what NEW and OLD are about) simply doesn't apply.

    If you want to use NEW (or OLD) in a trigger then you want the trigger to execute for each affected row and that means you want a row-level trigger:

    CREATE TRIGGER log_datei AFTER INSERT OR UPDATE OR DELETE
    ON dateien
    FOR EACH ROW
    EXECUTE PROCEDURE f_log_datei();
    

    I just changed FOR EACH STATEMENT to FOR EACH ROW.


    Your trigger should also be returning something:

    A trigger function must return either NULL or a record/row value having exactly the structure of the table the trigger was fired for.
    [...]
    The return value of a row-level trigger fired AFTER or a statement-level trigger fired BEFORE or AFTER is always ignored; it might as well be null. However, any of these types of triggers might still abort the entire operation by raising an error.

    So you should RETURN NEW; or RETURN NULL; in your trigger. You have an AFTER trigger so it doesn't matter which RETURN you use but I'd go with RETURN NEW;.

    0 讨论(0)
提交回复
热议问题