You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从PostgreSQL触发器函数代码中提取实际使用的列?

提取触发器代码中实际使用的列

背景与触发器示例

我有一批触发器,会在记录被更新或删除时将旧列值写入对应的历史表。以下是主表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;
$function$;

需求与期望输出

我需要提取触发器代码中实际使用的列,但查询pg_attribute只能获取表的全部列,无法匹配触发器里的真实使用情况(比如给contact新增列后,pg_attribute自动更新,但触发器未修改,结果就会不符)。

我计划通过正则从INSERT语句中提取数据并拆分为数组,具体提取目标和期望输出如下:

提取目标(从触发器代码中提取以下片段)

--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_name)
(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] -- 能去掉'OLD'前缀就更好了
vars_3 = [first_name, last_name, middle_name]
vars_4 = [OLD.first_name, OLD.last_name, OLD.middle_name]

目前我已经知道可以通过SELECT prosrc FROM pg_proc WHERE proname = 'contact_history_insert';获取触发器代码,但未找到更简便的系统表查询方式。

内容的提问来源于stack exchange,提问作者Missm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:55:24