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