介绍:
PostgreSQL数据库具有数百种存储的功能,包括过时的,未使用的等。
问题
我需要找出与表X有任何关系的所有存储函数-因为我想更改表结构。其中一些可能不会被使用,因此仅浏览代码就无法做到这一点。
我拥有ATM的解决方案正在运行psql \df+和grepping输出,但是我更喜欢类似数据库的解决方案,即使用信息模式。这绝对是一个重复的任务,我希望它干净整洁。
有什么建议?
介绍:
PostgreSQL数据库具有数百种存储的功能,包括过时的,未使用的等。
问题
我需要找出与表X有任何关系的所有存储函数-因为我想更改表结构。其中一些可能不会被使用,因此仅浏览代码就无法做到这一点。
我拥有ATM的解决方案正在运行psql \df+和grepping输出,但是我更喜欢类似数据库的解决方案,即使用信息模式。这绝对是一个重复的任务,我希望它干净整洁。
有什么建议?
Answers:
函数的主体只是存储为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,添加了真实的存储过程。您需要适应。有关:
EXECUTE几乎不可能涵盖动态查询。但是,可以使用大小写折叠~*代替~-或任何其他不区分大小写的模式匹配。
"MyTable"和的表MyTable,至少……说实话,那是“嗯,可以允许,但不是明智的”举动。
此查询非常易于使用:
SELECT proname, proargnames, prosrc FROM pg_proc WHERE prosrc ILIKE '%Text to search%';
EXECUTE诸如的表达式'mm_'||name_parameter,并且无法正确处理带引号的名称(如"my""table""大小写折叠),但可以满足大多数人的需求。