删除一组具有相似名称模式的模式

Fah*_*tha 5 postgresql dynamic-sql pattern-matching catalogs

考虑一种情况,需要执行一堆本质上相同的操作,唯一的变量是某个对象的名称。

在我的情况下,我需要删除一些模式,所有的形式ceu_shard_test_merge_*,以使用 shell globbing 术语。所以,从概念上讲,这可以写成

DROP SCHEMA ceu_shard_test_merge_* CASCADE;
Run Code Online (Sandbox Code Playgroud)

以类比 Unix shell。

当然这个命令不起作用,那么如何用一个命令来做到这一点呢?我的理解是,这不能以可移植的方式完成。我使用的是 PostgreSQL 8.4,但用于更新 PG 版本的方法也很好。

如果解决方案有一个试运行或虚拟选项,那就太好了,这样人们就可以在实际运行之前看到将要运行哪些命令。也许只是打印命令的一种方法?

此外,指示如何处理比给出的示例更通用的模式会很好。

Erw*_*ter 8

系统目录上的这个查询创建了必要的 DDL 脚本:

SELECT string_agg(format('DROP SCHEMA %I CASCADE;', nspname), E'\n')
FROM   pg_namespace
WHERE  nspname LIKE 'ceu_shard_test_merge_%';
Run Code Online (Sandbox Code Playgroud)

format()如有必要,请注意使用来转义标识符。

format()需要 PostgreSQL 9.1+。
替换为quote_ident()旧版本。

string_agg()需要 PostgreSQL 9.0+。
替换为array_to_string(array_agg(...), E'\n')旧版本。

对于 Postgres 8.4,这将是:

SELECT array_to_string(
          array_agg('DROP SCHEMA ' || quote_ident(nspname) || ' CASCADE;')
        , E'\n')
FROM ...
Run Code Online (Sandbox Code Playgroud)

返回:

DROP SCHEMA ceu_shard_test_merge_1 CASCADE;
DROP SCHEMA ceu_shard_test_merge_2 CASCADE;
...
Run Code Online (Sandbox Code Playgroud)

您可以在执行前检查。

您可以将其全部放入一个DO命令中自动执行或创建一个函数以供重复使用。对于完整的代码示例,请考虑这个密切相关的答案:

或者这个关于 SO 的相关答案

psql 中的输出

为了回应@Stew 的评论:要在 psql 中显示未经修饰的文本,您可以使用\pset元命令:

\pset format unaligned
\pset tuples_only
Run Code Online (Sandbox Code Playgroud)

或者使用短命令 \x \a


ETL*_*ETL 2

您可以使用 EXECUTE 编写一个过程,并通过循环遍历与 information_schema 表中的查询匹配的模式列表来在过程中构建语句。

然后,您可以从 psql 或其他传递您的标准(例如“ceu_shard_test_merge_%”)调用您的过程。

您可以有一个参数来执行此操作,或者只是进行空运行,而不是执行,然后它可以输出语句或类似的内容。