我想让 SQL 在 PostgreSQL 中删除一个函数。我DROP FUNCTION从pg_proc. 那不是问题。但是,如果我将参数留空,则不会删除该功能。
DROP FUNCTION
pg_proc
我检查了手册并写了然后我必须用它的参数识别函数来删除它,例如DROP FUNCTION some_func(text,integer)不仅仅是DROP FUNCTION some_func.
DROP FUNCTION some_func(text,integer)
DROP FUNCTION some_func
我在哪里可以找到参数?在表中的函数行中pg_proc没有参数。那么如何让 SQL 删除该函数呢?
Postgres 有一个专门用于此目的的功能。随 Postgres 8.4 引入。手册:
pg_get_function_identity_arguments(func_oid) …获取参数列表以标识函数(无默认值)… pg_get_function_identity_arguments返回标识函数所需的参数列表,例如,以它需要出现在 中的形式ALTER FUNCTION。这种形式省略了默认值。
pg_get_function_identity_arguments(func_oid) …获取参数列表以标识函数(无默认值)…
pg_get_function_identity_arguments(func_oid)
pg_get_function_identity_arguments返回标识函数所需的参数列表,例如,以它需要出现在 中的形式ALTER FUNCTION。这种形式省略了默认值。
pg_get_function_identity_arguments
ALTER FUNCTION
使用它(以及format())Postgres 9.1 引入的),以下查询生成 DDL 语句以删除与您的搜索词匹配的函数:
format()
SELECT format('DROP %s %I.%I(%s);' , CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END , n.nspname , p.proname , pg_catalog.pg_get_function_identity_arguments(p.oid) ) AS stmt FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE p.proname = 'dblink' -- function name -- AND n.nspname = 'public' -- schema name (optional) -- AND pg_catalog.pg_function_is_visible(p.oid) -- function visible to user ORDER BY 1;
系统目录pg_proc在Postgres 11 中发生了变化。proisagg替换为prokind,添加了真正的存储过程。你需要适应
proisagg
prokind
返回:
stmt --------------------------------------------------- DROP FUNCTION public.dblink(text); DROP FUNCTION public.dblink(text, boolean); DROP FUNCTION public.dblink(text, text); DROP FUNCTION public.dblink(text, text, boolean);
在示例中找到四个匹配项,因为 dblink 使用了重载函数。有选择地 运行DROP语句!
DROP
或者**,您可以使用方便的转换为[对象标识符类型regprocedure**,该类型返回一个完整的函数签名,包括参数类型:
regprocedure
-- SET LOCAL search_path = ''; -- optional, to get all names schema-qualified SELECT format('DROP %s %s;' , CASE WHEN proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END , oid::regprocedure ) AS stmt FROM pg_catalog.pg_proc WHERE proname = 'dblink' -- function name ORDER BY 1;