Question

Hi all,

I wrote a function in pl/pgsql and I have this problem:

I want use the values of NEW and OLD trigger record but I don't know the column name and number if the table.

for example:

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;
Was it helpful?

Solution

you know a original name - it is a variable TG_TABLE_NAME. And dynamic access to record fields is possible with EXECUTE USING statement.

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; $$;

This code is wrote by Tom Lane and it is from postgresql tricks pages Iteration over RECORD variable inside trigger.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top