当记录被更新或删除时,我有一些触发器可以用旧的列值更新表的相应历史表。这是一个触发器的例子,当主contact
表被更新时,该触发器会更新contact_history
表:
CREATE OR REPLACE FUNCTION public.contact_history_insert()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO public.contact_history
(dml_type, hard_deleted_on, first_name, last_name, middle_name)
VALUES
('D', now(), OLD.first_name OLD.last_name, OLD.middle_name)
RETURN OLD;
ELSEIF (TG_OP = 'UPDATE') THEN
INSERT INTO public.contact_history
(dml_type, first_name, last_name, middle_name)
VALUES
('U', OLD.first_name OLD.last_name, OLD.middle_name);
NEW.modified_on = now();
RETURN NEW;
END IF;
END;
我正在尝试编写一个查询,它允许我从触发器的过程代码中提取列,现在,我意识到我可以使用以下查询查询表pg_attribute
来获取触发器的信息:
SELECT att_name
FROM pg_attribute
WHERE attrelid = (SELECT tgrelid FROM pg_trigger WHERE tgname = 'contact_history_trigger')
AND attnum > 0;
但是,这并没有给予我想要的结果。这给出了将要更新的列的结果,但不是触发器中编写的过程代码中使用的实际列的结果。例如,如果我在contact
表中添加了一个新列,而没有更新contact触发器,它将自动更新pg_attribute
中的attname
。这与触发器代码中写入的实际列不相同。因此,我正在尝试编写一个查询,该查询将返回触发器代码中列出的列的结果。我意识到这可能包括使用正则表达式从INSERT INTO语句中提取数据,我还想将数据拆分为单个变量,并将它们放入新的数组变量中:
--Extract this data from the trigger code
(dml_type, hard_deleted_on, first_name, last_name, middle_name)
('D', now(), OLD.first_name, OLD.last_name, OLD.middle_namee)
(dml_type, first_name, last_name, middle_name)
('U', OLD.first_name OLD.last_name, OLD.middle_name)
---Expected output
vars_1 = [first_name, last_name, middle_name]
vars_2 = [OLD.first_name, OLD.last_name, OLD.middle_name] -- It would be a plus if it didn't extract the 'OLD' prefix
vars_3 = [first_name, last_name, middle_name]
vars_4 = [OLD.first_name, OLD.last_name, OLD.middle_name]
这看起来确实过于复杂,但我还没有找到一种更简单的方法,只需调用系统表(如pg_attribute
或information_schema.triggers
)来检索数据,而不会出现我正在寻找的错误信息。
我知道这个查询返回触发器的实际过程代码:
SELECT prosrc FROM pg_proc WHERE proname = 'contact_history_insert';
1条答案
按热度按时间gab6jxml1#
如果表中的列顺序相同,并且历史记录表中的附加字段仅位于表的末尾,则可以按如下方式编写查询。
第二种方法是在触发器中使用动态查询,可以使用
information_schema
获取表列名