Postgresql 使用旧的in触发器动态获取列名称

Postgresql 使用旧的in触发器动态获取列名称,postgresql,plpgsql,procedure,Postgresql,Plpgsql,Procedure,我想写一个通用触发器函数(Postgres过程)。有许多主表,如TableA、TableB等,以及相应的审计表TableA\u audit、TableB\u audit。结构如下所示 TableA和TableA_Audit有aa integer、ab integer列 TableB和TableB_Audit有列ba integer 类似地,可以有许多主表及其审计表 要求是,如果主表中的任何一个得到更新,那么它们的条目应该插入到各自的审计表中 如果表A有这样的条目

我想写一个通用触发器函数(Postgres过程)。有许多主表,如TableA、TableB等,以及相应的审计表TableA\u audit、TableB\u audit。结构如下所示

TableA和TableA_Audit有aa integer、ab integer列

TableB和TableB_Audit有列ba integer

类似地,可以有许多主表及其审计表

要求是,如果主表中的任何一个得到更新,那么它们的条目应该插入到各自的审计表中

如果表A有这样的条目

                ---------------------
                |     **TableA**   |
                ---------------------
                |aa      | ab       |
                |--------|----------|
                |    5   |  10      |
                ---------------------        
foreach i in array  column_names
loop
 raise notice '%', old.i;
end loop;
然后我写了一个更新,比如

更新表格A集合aa=aa+15

然后,TableA的旧值应插入TableA_审计表中,如下所示

表A\u审计包括:-

                ---------------------
                |  **TableA_Audit** |
                ---------------------
                |aa      | ab       |
                |--------|----------|
                |    5   |  10      |
                ---------------------  
为了简化上述场景,我编写了一个名为insert_in_audit的通用函数。每当主表中有任何更新时,都应该调用函数insert\u in\u audit。该功能应实现以下功能:-

  • 使用主表在相应的audit_表中动态插入条目。如果表B中有更新,则只应在表B_Audit中插入条目
  • 到目前为止,我所能做到的是。我已经得到了主表中发生更新的所有列的名称。 例如:对于query-updatetableasetaa=aa+15,我能够在varchar数组中获得TableA中的所有列名称

    列名称varchar[]:='{“aa”,“ab”}'

    我的问题是如何得到列aa和ab的旧值。我试着这样做

                    ---------------------
                    |     **TableA**   |
                    ---------------------
                    |aa      | ab       |
                    |--------|----------|
                    |    5   |  10      |
                    ---------------------        
    
    foreach i in array  column_names
    loop
     raise notice '%', old.i;
    end loop;
    

    但是上面给了我错误:-记录“old”没有字段“i”。有人能帮我找到旧的价值观吗

    下面是一个代码示例,您可以如何从PL/pgSQL中的
    OLD
    动态提取值:

    CREATE FUNCTION dynamic_col() RETURNS trigger
       LANGUAGE plpgsql AS
    $$DECLARE
       v_col name;
       v_val text;
    BEGIN
       FOREACH v_col IN ARRAY TG_ARGV
       LOOP
          EXECUTE format('SELECT (($1).%I)::text', v_col)
             USING OLD
             INTO v_val;
          RAISE NOTICE 'OLD.% = %', v_col, v_val;
       END LOOP;
    
       RETURN OLD;
    END;$$;
    
    CREATE TABLE trigtest (
       id integer,
       val text
    );
    
    INSERT INTO trigtest VALUES
       (1, 'one'), (2, 'two');
    
    CREATE TRIGGER dynamic_col AFTER DELETE ON trigtest
       FOR EACH ROW EXECUTE FUNCTION dynamic_col('id', 'val');
    
    DELETE FROM trigtest WHERE id = 1;
    
    NOTICE:  OLD.id = 1
    NOTICE:  OLD.val = one
    

    下面是一个代码示例,说明如何从PL/pgSQL中的
    OLD
    动态提取值:

    CREATE FUNCTION dynamic_col() RETURNS trigger
       LANGUAGE plpgsql AS
    $$DECLARE
       v_col name;
       v_val text;
    BEGIN
       FOREACH v_col IN ARRAY TG_ARGV
       LOOP
          EXECUTE format('SELECT (($1).%I)::text', v_col)
             USING OLD
             INTO v_val;
          RAISE NOTICE 'OLD.% = %', v_col, v_val;
       END LOOP;
    
       RETURN OLD;
    END;$$;
    
    CREATE TABLE trigtest (
       id integer,
       val text
    );
    
    INSERT INTO trigtest VALUES
       (1, 'one'), (2, 'two');
    
    CREATE TRIGGER dynamic_col AFTER DELETE ON trigtest
       FOR EACH ROW EXECUTE FUNCTION dynamic_col('id', 'val');
    
    DELETE FROM trigtest WHERE id = 1;
    
    NOTICE:  OLD.id = 1
    NOTICE:  OLD.val = one
    

    你用的是MySQL还是Postgresql?我用的是postgres@Abhishek请仅使用适当的SQL变体标记问题。@jarlh ah。。。没有意识到这是一个反问。。。抱歉…如果您想要一个通用的审计触发器,为什么不使用许多解决方案呢。e、 或者你正在使用MySQL或Postgresql?我正在使用postgres@Abhishek请仅使用适当的SQL变体标记问题。@jarlh ah。。。没有意识到这是一个反问。。。抱歉…如果您想要一个通用的审计触发器,为什么不使用许多解决方案呢。e、 g.或