【问题标题】:pl/pgsql: How show values of NEW & OLD trigger record if i don't know the name of original table colum?pl/pgsql:如果我不知道原始表列的名称,如何显示 NEW & OLD 触发器记录的值?
【发布时间】:2014-02-11 14:45:23
【问题描述】:

大家好,

我在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;

【问题讨论】:

    标签: sql postgresql triggers record plpgsql


    【解决方案1】:

    您知道一个原始名称 - 它是一个变量 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

    【讨论】:

    • 你也可以作弊使用hstore(NEW)
    • 谢谢。你是我的救命恩人!
    猜你喜欢
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多