Postgres 用值数组替换函数

Postgres replace function with an array of values

有没有一种方法可以使用输入值数组一次性替换不同的字符串?

假设我们有一个 input['a', 'b', 'c', 'd'] 数组和一个 replacement['1', '2', '3', '4'] 数组。 现在,如果我们要执行以下操作:

UPDATE table SET field=replace('a string to be replaced', input, replacement)

每个 a 将被替换为 replacement 相同索引('1')上的任何内容,每个 b 将被替换为 replacement 相同索引('2'), 等等,所以 field 会变成 '1 string to 2e repl12e4'.

(使用 Postgres 9.4)

编辑:

再比如,input就是['string', 'replaced']replacement就是['cat', 'dog']field就会变成'a cat to be dog'

此类任务的自然方法是在自定义函数中使用循环:

create or replace function multireplace_loop
    (string text, pattern text[], replacement text[])
returns text language plpgsql immutable as $$
declare
    rec record;
begin
    for rec in
        select ord, old_str, new_str
        from unnest(pattern, replacement) 
        with ordinality as o(old_str, new_str, ord)
        order by ord
    loop
        string:= replace(string, rec.old_str, rec.new_str);
    end loop;
    return string;
end $$;

select multireplace_loop
    ('a string to be replaced', '{string, replaced}', '{cat, dog}');

有一个优雅的纯 SQL 应用递归查询的替代解决方案:

create or replace function multireplace_recursive
    (string text, pattern text[], replacement text[])
returns text language sql immutable as $$
    with recursive input_rows as (
        select ord, old_str, new_str
        from unnest(pattern, replacement) 
        with ordinality as o(old_str, new_str, ord)
    ),
    recursive_replace as (
        select ord, replace(string, old_str, new_str) as string
        from input_rows
        where ord = 1
    union all
        select i.ord, replace(string, i.old_str, i.new_str)
        from recursive_replace r
        join input_rows i on i.ord = r.ord+ 1
    )
    select string
    from recursive_replace
    order by ord desc
    limit 1
$$;

select multireplace_recursive
    ('a string to be replaced', '{string, replaced}', '{cat, dog}');

Db<>Fiddle.

中测试