借助 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
时才相关。
性能会相差几个数量级。
我正在寻找一些技巧来使这个 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
时才相关。
性能会相差几个数量级。