我想让SQL在PostgreSQL中删除一个函数。我从DROP FUNCTION
写pg_proc
和get函数名。那不是问题。但是,如果我留下空白参数,它将不会丢弃该功能。
我检查了手册,然后写了然后我必须用它的参数识别函数来放弃它,例如DROP FUNCTION some_func(text,integer)
而不仅仅是DROP FUNCTION some_func
。
我在哪里可以找到参数?在pg_proc
表的函数行中没有参数。那么如何让SQL删除该函数呢?
Postgres具有专门用于此目的的功能。 Postgres 8.4推出。 The manual:
pg_get_function_identity_arguments(func_oid)
...获取参数列表以识别函数(没有默认值)...
pg_get_function_identity_arguments
返回标识函数所必需的参数列表,例如,它需要以ALTER FUNCTION
中的形式出现。此表单省略了默认值。
使用它(以及与Postgres 9.1一起引入的format()
),以下查询生成DDL语句以删除与搜索项匹配的函数:
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
取代,添加了真正的存储过程。你需要适应。看到:
返回:
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使用overloaded functions。
有选择地运行DROP
语句!
或者,您可以使用方便的强制转换为object identifier type 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;
使用pgadminIII并直接访问功能列表并右键单击它然后选择删除
在Postgres 10中,只要在模式中它是唯一的,就可以在不知道参数列表的情况下删除函数。
drop function if exists some_func;
当然,如果你重载了这个函数(或者试图删除多个模式),你仍然需要上面的答案。
如果你正在使用旧版本的postgres,其中pg_get_function_identity_arguments(func_oid)不存在,我创建自己的函数从函数中获取参数,你只需要为函数传递oid,你需要部署以下函数到你的postgres db。
CREATE OR REPLACE FUNCTION public.getFunctionParameter(functionOid oid)
RETURNS text AS
$BODY$
declare
t_paras text;
paras oid[];
res text :='(';
begin
select proargtypes into t_paras from pg_proc where oid=functionOid;
if t_paras is null or t_paras='' then
return '()';
else
paras:=string_to_array(t_paras,' ');
for i in array_lower(paras,1) .. array_upper(paras,1)
loop
raise notice 'para is %',paras[i];
select format_type(paras[i]::oid,NULL) into t_paras;
res:=res||t_paras||',';
end loop;
res:=substring(res from 1 for char_length(res)-1);
res:=res||')';
return res;
end if;
end
$BODY$
LANGUAGE plpgsql ;
下面的函数将列出函数名称和参数,如果要在其他模式下获取函数,则更改模式名称,例如我使用public
SELECT n.nspname||'.'||p.proname||public.getFunctionParameter(p.oid)
FROM pg_proc p JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname='public'
你将得到如下结果
1 "public.getfunctionparameter(integer,text)"
2 "public.getfunctionparameter(oid)"