如何保持循环甚至发生错误?
How to keep looping even error happend?
我写了一个 PL/pgsql 来在 tables
上批量创建索引
CREATE OR REPLACE FUNCTION create_index() RETURNS void AS
$BODY$
DECLARE
r INTEGER;
BEGIN
FOR r IN 1..1000
LOOP
EXECUTE format(
' CREATE INDEX idx_abc_id_' || r::text ||
' ON abc_id_' || r::text ||
' USING btree
(key);');
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql;
它有一个问题,如果分区 abc_500 不存在,那么如何创建索引函数将失败并且什么都不做。
即使 create_index 在其中一个 table 上出错,如何使循环继续进行?
我认为更好的方法是不对循环的数字进行硬编码,而是迭代现有的 tables:
CREATE OR REPLACE FUNCTION create_index() RETURNS void AS
$BODY$
DECLARE
r record;
BEGIN
FOR r IN select tablename, regexp_replace(tablename, '[^0-9]+','') as idx_nr
from pg_tables
where tablename ~ 'abc_id_[0-9]+'
LOOP
EXECUTE format('CREATE INDEX %I ON %I USING btree (key)',
'idx_abc_id_'||r.idx_nr,
r.tablename);
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql;
当您使用 format()
函数时,最好使用适当的标识符占位符。
如果您还想在现有 table 上创建索引时忽略任何错误,则需要捕获异常并忽略它:
CREATE OR REPLACE FUNCTION create_index() RETURNS void AS
$BODY$
DECLARE
r record;
msg text;
BEGIN
FOR r IN select tablename, regexp_replace(tablename, '[^0-9]+','') as idx_nr
from pg_tables
where tablename ~ 'abc_id_[0-9]+'
LOOP
BEGIN
EXECUTE format('CREATE INDEX %I ON %I USING btree (key)',
'idx_abc_id_'||r.idx_nr,
r.tablename);
EXCEPTION
WHEN OTHERS THEN
GET STACKED DIAGNOSTICS msg = MESSAGE_TEXT;
RAISE NOTICE 'Could not create index for: %, %', r.idx_nr, msg;
END;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql;
我写了一个 PL/pgsql 来在 tables
上批量创建索引CREATE OR REPLACE FUNCTION create_index() RETURNS void AS
$BODY$
DECLARE
r INTEGER;
BEGIN
FOR r IN 1..1000
LOOP
EXECUTE format(
' CREATE INDEX idx_abc_id_' || r::text ||
' ON abc_id_' || r::text ||
' USING btree
(key);');
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql;
它有一个问题,如果分区 abc_500 不存在,那么如何创建索引函数将失败并且什么都不做。
即使 create_index 在其中一个 table 上出错,如何使循环继续进行?
我认为更好的方法是不对循环的数字进行硬编码,而是迭代现有的 tables:
CREATE OR REPLACE FUNCTION create_index() RETURNS void AS
$BODY$
DECLARE
r record;
BEGIN
FOR r IN select tablename, regexp_replace(tablename, '[^0-9]+','') as idx_nr
from pg_tables
where tablename ~ 'abc_id_[0-9]+'
LOOP
EXECUTE format('CREATE INDEX %I ON %I USING btree (key)',
'idx_abc_id_'||r.idx_nr,
r.tablename);
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql;
当您使用 format()
函数时,最好使用适当的标识符占位符。
如果您还想在现有 table 上创建索引时忽略任何错误,则需要捕获异常并忽略它:
CREATE OR REPLACE FUNCTION create_index() RETURNS void AS
$BODY$
DECLARE
r record;
msg text;
BEGIN
FOR r IN select tablename, regexp_replace(tablename, '[^0-9]+','') as idx_nr
from pg_tables
where tablename ~ 'abc_id_[0-9]+'
LOOP
BEGIN
EXECUTE format('CREATE INDEX %I ON %I USING btree (key)',
'idx_abc_id_'||r.idx_nr,
r.tablename);
EXCEPTION
WHEN OTHERS THEN
GET STACKED DIAGNOSTICS msg = MESSAGE_TEXT;
RAISE NOTICE 'Could not create index for: %, %', r.idx_nr, msg;
END;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql;