借助 plpgsql 在一次更新中进行多个正则表达式更改

Do multiple regex changes in one update with the help of plpgsql

我正在寻找一些技巧来使这个 PostgreSQL plpgsql 函数起作用。我想在每条记录上做几个正则表达式并且只更新一次,因为一个一个地做它们需要 15 分钟。 ...

CREATE OR REPLACE FUNCTION clean_column() RETURNS void  AS $$
    DECLARE
        r record;
        reg text[] := array[ 
          ['search','replace'], 
          ['search','replace'],
          ['search','replace'],
          ['search','replace'] 
        ];
        var text[];
        tmp text;
    BEGIN
        for r in 
            select column from mytable
            loop -- loop over all records
                tmp = r;
                FOREACH var SLICE 1 IN ARRAY reg
                LOOP -- loop over all changes
                    tmp = regexp_replace(tmp,var[1],var[2]);
                END LOOP;
                UPDATE mytable SET r = tmp;
        end loop;
    END
$$ LANGUAGE plpgsql;

... r 存在问题,因为它未分配。可能是我对 plpgsql 的工作原理缺乏了解。

也许还有其他方法可以对记录字段进行多项更改?

您的函数会重复更新该行,每次都写入一个新的行版本。那仍然是非常低效的。

重点必须是只更新每一行一次。并且只有当任何事情真正发生变化时。

CREATE OR REPLACE FUNCTION clean_column(INOUT _text text)
  LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE AS
$func$
DECLARE
   _reg CONSTANT text[] := ARRAY[ 
       ['search','replace']
     , ['search','replace']
     , ['search','replace']];
   _var text[];
BEGIN
   FOREACH _var SLICE 1 IN ARRAY _reg
   LOOP
      _text := regexp_replace(_text, _var[1], _var[2]);
   END LOOP;
END
$func$;

该函数不运行 UPDATE 本身,只是字符串处理。像这样在 UPDATE 中使用该函数:

UPDATE tbl
SET    col = clean_column(col)
WHERE  col IS DISTINCT FROM clean_column(col)  -- ① !
AND    col IS NOT NULL  -- ② ?

① 跳过不会改变任何内容的更新。

② 尽早跳过带有 NULL 的行(甚至不评估函数)。当然,只有当列可以是 NULL 时才相关。

性能会相差几个数量级。