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 版本的方法也很好。
如果解决方案有一个试运行或虚拟选项,那就太好了,这样人们就可以在实际运行之前看到将要运行哪些命令。也许只是打印命令的一种方法?
此外,指示如何处理比给出的示例更通用的模式会很好。
系统目录上的这个查询创建了必要的 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 的相关答案。
为了回应@Stew 的评论:要在 psql 中显示未经修饰的文本,您可以使用\pset元命令:
\pset format unaligned
\pset tuples_only
Run Code Online (Sandbox Code Playgroud)
或者使用短命令 \x \a
您可以使用 EXECUTE 编写一个过程,并通过循环遍历与 information_schema 表中的查询匹配的模式列表来在过程中构建语句。
然后,您可以从 psql 或其他传递您的标准(例如“ceu_shard_test_merge_%”)调用您的过程。
您可以有一个参数来执行此操作,或者只是进行空运行,而不是执行,然后它可以输出语句或类似的内容。
| 归档时间: |
|
| 查看次数: |
6263 次 |
| 最近记录: |