大家好,
我在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;
答案 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。