介绍:
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""
大小写折叠),但可以满足大多数人的需求。