Postgres regexp使用另一个表替换正则表达式和替换值

时间:2017-09-12 22:04:00

标签: sql postgresql

假设我有一个带键/值的表,其中键是正则表达式,相应的值是替换值。例如:

table_a:

Key   Value
-----------
a     123
b     456
c     789

我需要使用SQL更新另一个表中的值,方法是将上表中显示的每个键替换为相应的值。

如果我有一个替换值,我会使用这样的东西:

UPDATE table_b 
SET    some_field = REGEXP_REPLACE((SELECT STRING_AGG(table_a.key, '|') 
                                    FROM   table_a), 'replacement value'); 

这将基于table_a中的所有keys构造一个正则表达式,并用替换字符串替换任何匹配项。

我怎样才能做类似的事情,但是使用table_a中相应的value作为替换值?

使用Postgres 9.5

1 个答案:

答案 0 :(得分:1)

您只能在regexp_replace()的单次执行中执行此操作。对于regexp_replace()的所有行,您需要循环和多次调用table_a。所以,你需要一个plpgsql函数:

create or replace function replace_all_patterns(str text)
returns text language plpgsql as $$
declare
    r record;
begin
    for r in
        select key, value
        from table_a
    loop
        str:= regexp_replace(str, r.key, r.value, 'g');
    end loop;
    return str;
end $$;

假设table_b包含两行:

create table table_b(some_field text);
insert into table_b values
('abc'),
('ccc');

你可以这样使用这个功能:

update table_b
set some_field = replace_all_patterns(some_field)
returning *;

 some_field 
------------
 123456789
 789789789
(2 rows)

值得补充的是,该功能相当昂贵,在某些情况下,结果可能取决于table_a中行的顺序。