pl / pgsql:如何显示NEW&的值。如果我不知道原始表colum的名称,OLD触发器记录?

时间:2014-02-11 14:45:23

标签: sql postgresql triggers record plpgsql

大家好,

我在pl / pgsql中编写了一个函数,我遇到了这个问题:

我想使用NEW和OLD触发器记录的值但是我不知道列表中的列名和数字。

例如:

CREATE OR REPLACE FUNCTION tt() RETURNS trigger AS $$
DECLARE

text1 text;
text2 text;
orig_name   text    =tg_argv[0];
orig_schema     text    =tg_argv[1];
log_name    text    =tg_argv[2];
log_schema  text    =tg_argv[3];
col pg_attribute.attname%TYPE;
[...]

BEGIN
orig_comp := quote_ident(orig_schema)||'.'||quote_ident(orig_name);
log_comp := quote_ident(log_schema)||'.'||quote_ident(log_name);

IF(trigger_mode='INSERT') 
THEN 
-- I want know the names of column  
    FOR colonna in
      SELECT attname
      FROM   pg_attribute
      WHERE  attrelid = orig_comp::regclass
      AND    attnum > 0
      AND    NOT attisdropped

    loop --for each column I want save the value like a string
      text1=NEW||'.'||colonna; -- this don't work: error: record NEW don't have colonna like values
      text2:=text2||' , '||text1;
    end loop;

[...]


END IF; 

[...]       
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

1 个答案:

答案 0 :(得分:4)

您知道原始名称 - 它是变量TG_TABLE_NAME。使用EXECUTE USING语句可以动态访问记录字段。

CREATE OR REPLACE FUNCTION dynamic_trigger()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
DECLARE
    ri RECORD;
    t TEXT;
BEGIN
    RAISE NOTICE E'\n    Operation: %\n    Schema: %\n    Table: %',
        TG_OP,
        TG_TABLE_SCHEMA,
        TG_TABLE_NAME;
    FOR ri IN
        SELECT ordinal_position, column_name, data_type
        FROM information_schema.columns
        WHERE
            table_schema = quote_ident(TG_TABLE_SCHEMA)
        AND table_name = quote_ident(TG_TABLE_NAME)
        ORDER BY ordinal_position
    LOOP
        EXECUTE 'SELECT ($1).' || ri.column_name || '::text' INTO t USING NEW;
        RAISE NOTICE E'Column\n    number: %\n    name: %\n    type: %\n    value: %.',
            ri.ordinal_position,
            ri.column_name,
            ri.data_type,
            t;
    END LOOP;
    RETURN NEW;
END; $$;

此代码由Tom Lane编写,它来自postgresql技巧页面Iteration over RECORD variable inside trigger