在循环中使用 replace()
Using replace() inside a loop
我正在尝试将索引从物化视图复制到表中。这是我正在尝试使用的脚本:
DO $$
declare indexdefname record;
a text;
b text;
c text;
begin for indexdefname in
select indexdef
from pg_indexes i
join pg_class c
on schemaname = relnamespace::regnamespace::text
and tablename = relname
where relkind = 'm'
loop
a:= FORMAT ('do $check$ begin replace(%s, public.,
myschema. ); end $check$', indexdef.indexdefname);
execute a;
end loop;
end $$;
这是我遇到的错误:
missing FROM-clause entry for table "indexdef".
所有,我正在尝试做的是替换
CREATE INDEX test_index
ON public.test
( name )
和
CREATE INDEX test_index
ON myschema.test
( name )
您报告错误的直接原因是切换器:
你有 indexdef.indexdefname
应该是 indexdefname.indexdef
.
但还有更多。不要仅为替换构建动态嵌套 DO
语句。这是一个简单的函数调用,可以立即嵌套在初始 SELECT
中。此外,还有多个语法错误:缺少引号、未赋值的函数调用以及 DDL 语句从未执行。只需执行 CREATE INDEX
命令。喜欢:
DO
$do$
DECLARE
_ddl text;
BEGIN
SELECT INTO _ddl
string_agg(replace(i.indexdef, 'ON public.', 'ON myschema.'), E';\n')
FROM pg_indexes i
JOIN pg_class c ON c.relnamespace::regnamespace::text = i.schemaname
AND c.relname = i.tablename
WHERE c.relkind = 'm';
IF _ddl IS NULL THEN
RAISE EXCEPTION 'No indexes found!';
ELSE
EXECUTE _ddl;
END IF;
END
$do$;
小心! 这使用 all 索引 all 物化视图。替换 - 虽然看起来合理 - 可能会在极端情况下出错。您可能想要更有选择性,或者采用更安全、非动态的两步法:
1.生成DDL字符串
SELECT string_agg(replace(i.indexdef, 'ON public.', 'ON myschema.'), E';\n')
FROM pg_indexes i
JOIN pg_class c ON c.relnamespace::regnamespace::text = i.schemaname
AND c.relname = i.tablename
WHERE c.relkind = 'm'; -- more predicates?
2. 执行字符串 after 检查它是否符合您的要求。
我正在尝试将索引从物化视图复制到表中。这是我正在尝试使用的脚本:
DO $$
declare indexdefname record;
a text;
b text;
c text;
begin for indexdefname in
select indexdef
from pg_indexes i
join pg_class c
on schemaname = relnamespace::regnamespace::text
and tablename = relname
where relkind = 'm'
loop
a:= FORMAT ('do $check$ begin replace(%s, public.,
myschema. ); end $check$', indexdef.indexdefname);
execute a;
end loop;
end $$;
这是我遇到的错误:
missing FROM-clause entry for table "indexdef".
所有,我正在尝试做的是替换
CREATE INDEX test_index
ON public.test
( name )
和
CREATE INDEX test_index
ON myschema.test
( name )
您报告错误的直接原因是切换器:
你有 应该是 indexdef.indexdefname
indexdefname.indexdef
.
但还有更多。不要仅为替换构建动态嵌套 DO
语句。这是一个简单的函数调用,可以立即嵌套在初始 SELECT
中。此外,还有多个语法错误:缺少引号、未赋值的函数调用以及 DDL 语句从未执行。只需执行 CREATE INDEX
命令。喜欢:
DO
$do$
DECLARE
_ddl text;
BEGIN
SELECT INTO _ddl
string_agg(replace(i.indexdef, 'ON public.', 'ON myschema.'), E';\n')
FROM pg_indexes i
JOIN pg_class c ON c.relnamespace::regnamespace::text = i.schemaname
AND c.relname = i.tablename
WHERE c.relkind = 'm';
IF _ddl IS NULL THEN
RAISE EXCEPTION 'No indexes found!';
ELSE
EXECUTE _ddl;
END IF;
END
$do$;
小心! 这使用 all 索引 all 物化视图。替换 - 虽然看起来合理 - 可能会在极端情况下出错。您可能想要更有选择性,或者采用更安全、非动态的两步法:
1.生成DDL字符串
SELECT string_agg(replace(i.indexdef, 'ON public.', 'ON myschema.'), E';\n')
FROM pg_indexes i
JOIN pg_class c ON c.relnamespace::regnamespace::text = i.schemaname
AND c.relname = i.tablename
WHERE c.relkind = 'm'; -- more predicates?
2. 执行字符串 after 检查它是否符合您的要求。