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}');
中测试
有没有一种方法可以使用输入值数组一次性替换不同的字符串?
假设我们有一个 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}');
中测试