【问题标题】:Postgres dynamic insert in trigger functionPostgres 在触发函数中动态插入
【发布时间】:2021-12-21 11:59:15
【问题描述】:

我正在尝试创建一个将新记录动态插入审计表的触发器函数。

CREATE OR REPLACE FUNCTION schema.table()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
    _tablename text;
    BEGIN
        _tablename := 'user_audit';
        EXECUTE 'INSERT INTO audit.' || quote_ident(_tablename) || ' VALUES ($1.*)' USING OLD;
        RETURN NEW;
    END;
$BODY$;

上面的触发器功能可以正常工作,因为它可以将 OLD 中的所有内容按预期插入到审计表中。但是,我的表中有一个名为 timestampzt_range 的 tstzrange 范围列,我需要做的是使用 LOWER(OLD.timestampzt_range)、LOWER(NEW.timestampzt_range) 在审计表中为其设置值。如果我想在多个表上使用此触发器函数,如何在不使用如下插入语句的情况下动态实现这一点。

INSERT INTO audit.user_audit
    (
        column_1,
        column_2,
        timestampzt_range 
    )
    VALUES
    (
        OLD.column_1,
        OLD.column_2,       
        tstzrange(LOWER(OLD.timestampzt_range), LOWER(NEW.timestampzt_range))
    );

我只需要在更新时使用它,如果我可以实现动态语句,表名将作为参数传递给触发函数。只有审计列在整个数据库中是一致的,所以对我来说重要的是使用 OLD 创建插入或以某种方式动态地从中提取除 timestampzt_range 之外的所有内容,然后使用 tstzrange(LOWER(OLD.timestampzt_range), LOWER(NEW.timestampzt_range)) 作为范围列的值。

【问题讨论】:

    标签: postgresql triggers range


    【解决方案1】:

    第一条评论:您只能在UPDATE 触发器中使用NEWOLD 关键字。在 INSERT 触发器中,OLD 不存在。在 DELETE 触发器中,NEW 不存在。请参阅manual

    然后你可以在你的触发函数中替换

    'INSERT INTO audit.' || quote_ident(_tablename) || ' VALUES ($1.*)' USING OLD

    通过

    'INSERT INTO audit.' || quote_ident(_tablename) || ' VALUES (OLD.column_1, OLD.column_2, tstzrange(LOWER(OLD.timestampzt_range), LOWER(NEW.timestampzt_range)))'

    这样才能达到您的预期效果。

    最后但同样重要的是,您的动态语句EXECUTE 'INSERT INTO audit.' ... 是无用的,因为_tablename 是函数内部声明的静态参数。

    【讨论】:

    • @ Edouard H. 我只需要在更新时使用它,如果我可以实现动态语句,表名将作为参数传递给触发器函数。只有审计列在整个数据库中是一致的,所以对我来说重要的是使用 OLD 创建插入或以某种方式动态地从中提取除 timestampzt_range 之外的所有内容,然后使用 tstzrange(LOWER(OLD.timestampzt_range), LOWER(NEW.timestampzt_range)) 作为范围列的值。
    • 触发器函数不接受输入参数,请参阅manual:“使用 CREATE FUNCTION 命令创建触发器函数,将其声明为不带参数的函数”。然后OLD.timestampzt_rangeINSERT 触发器中不被接受,因为它没有任何意义。问题是:当您插入新行时,这些信息从何而来?一般来说,您应该回到您的需求,而不是挖掘可能不适合您需求的解决方案。
    猜你喜欢
    • 2011-12-16
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2010-10-03
    • 1970-01-01
    • 2012-06-15
    相关资源
    最近更新 更多