Postgresql的通用字符串修剪触发器

时间:2018-01-04 18:25:16

标签: postgresql triggers

问题:

我工作的公司的所有者之一拥有直接数据库访问权限。他在Windows笔记本上使用Navicat。显然,它有一个他喜欢从Excel导入数据的功能。问题是文本字段经常(或可能总是)最终以\ r \ n结尾。这可能导致显示,报告和过滤问题。我被要求清理它并阻止他这样做。

我知道我可以为每个表添加一个触发器来执行类似的操作:

https://httpbin.org/

但是,我更愿意不为他有权访问的每个表写一个单独的触发器函数(超过100个)。我的想法是只编写一个泛型函数,然后传入一个我希望通过NEW.customer_name := regexp_replace(NEW.customer_name, '\r\n', '', 'g'); 参数更正的列名数组。

有没有办法根据TG_ARGV数组动态更新触发器TG_ARGV[]记录?

详细说明:

我在x86_64-pc-linux-gnu上使用PostgreSQL 9.6.6

1 个答案:

答案 0 :(得分:1)

在plpgsql触发器函数中没有动态访问new记录列的本机方法。我知道的唯一方法是将记录转换为jsonb,修改它并使用jsonb_populate_record()将其转换回记录:

create or replace function a_trigger()
returns trigger language plpgsql as $$
declare
    j jsonb = to_jsonb(new);
    arg text;
begin
    foreach arg in array tg_argv loop
        if j->>arg is not null then
            j = j || jsonb_build_object(arg, regexp_replace(j->>arg, e'\r\n', '', 'g'));
        end if;
    end loop;
    new = jsonb_populate_record(new, j);
    return new;
end;
$$;

如果可以use plpython:

,情况要简单得多
create or replace function a_trigger()
returns trigger language plpython3u as $$
    import re
    new = TD["new"]
    for col in TD["args"]:
        new[col] = re.sub(r"\r\n", "", new[col])
    return "MODIFY"
$$;