PostgreSQL:如何列出访问特定表的所有存储函数


13

介绍:

PostgreSQL数据库具有数百种存储的功能,包括过时的,未使用的等。

问题

我需要找出与表X有任何关系的所有存储函数-因为我想更改表结构。其中一些可能不会被使用,因此仅浏览代码就无法做到这一点。

我拥有ATM的解决方案正在运行psql \df+和grepping输出,但是我更喜欢类似数据库的解决方案,即使用信息模式。这绝对是一个重复的任务,我希望它干净整洁。

有什么建议?

Answers:


18

函数的主体只是存储为string。没有引用对象的列表。(例如,与视图不同,在视图中保存了到引用表的实际链接。)

对于Postgres 10或更早版本的查询使用系统目录信息功能pg_get_functiondef()来重构CREATE FUNCTION相关功能的脚本,并使用不区分大小写的正则表达式搜索表名:

SELECT n.nspname AS schema_name
     , p.proname AS function_name
     , pg_get_function_arguments(p.oid) AS args
     , pg_get_functiondef(p.oid) AS func_def
FROM   pg_proc p
JOIN   pg_namespace n ON n.oid = p.pronamespace
WHERE  NOT p.proisagg
AND    n.nspname NOT LIKE 'pg_%'
AND    n.nspname <> 'information_schema'
AND    pg_get_functiondef(p.oid) ~* '\mbig\M';

它应该可以完成工作,但是显然不是防弹的。对于动态生成表名的动态SQL可能会失败,并且它可能返回任意数量的误报-尤其是在表名是常用词的情况下。

聚合功能和系统架构中的所有功能均被排除。

\m\M在正则表达式中标记单词的开头和结尾。

pg_proc在Postgres 11 proisagg中更改的系统目录已替换为prokind,添加了真实的存储过程。您需要适应。有关:


1
是的...它并不完全健壮,在某种意义上说它找不到EXECUTE诸如的表达式'mm_'||name_parameter,并且无法正确处理带引号的名称(如"my""table""大小写折叠),但可以满足大多数人的需求。
Craig Ringer 2013年

@CraigRinger:是的,EXECUTE几乎不可能涵盖动态查询。但是,可以使用大小写折叠~*代替~-或任何其他不区分大小写的模式匹配。
Erwin Brandstetter

只要操作员不够疯狂就不能实际创建名为"MyTable"和的表MyTable,至少……说实话,那是“嗯,可以允许,但不是明智的”举动。
Craig Ringer 2013年

感谢你的回答!我实际上不在任何地方使用动态表名构造,并且所有表名都是小写的。
Sergey Kudriavtsev

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.