我想让SQL在PostgreSQL中删除一个函数。我从DROP FUNCTION
写了pg_proc
和一个get函数名。那不是问题。但是,如果我留下空白参数,它将不会丢弃该功能。
我检查了手册,然后写了,然后我必须用它的参数来识别该功能,例如DROP FUNCTION some_func(text,integer)
而不仅仅是DROP FUNCTION some_func
。
我在哪里可以找到参数?在pg_proc
表中的函数行中,没有参数。那么如何让SQL删除该函数呢?
答案 0 :(得分:31)
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;
Postgres 11 中的系统目录pg_proc
已更改。 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;
答案 1 :(得分:1)
使用pgadminIII并直接访问功能列表并右键单击它然后选择删除
答案 2 :(得分:1)
在Postgres 10中,只要在模式中它是唯一的,就可以在不知道参数列表的情况下删除函数。
drop function if exists some_func;
当然,如果你重载了这个函数(或者试图删除多个模式),你仍然需要上面的答案。
答案 3 :(得分:0)
如果您正在使用旧版本的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)"