【问题标题】:How to get function parameter lists (so I can drop a function)如何获取函数参数列表(这样我就可以删除一个函数)
【发布时间】:2012-08-21 01:45:05
【问题描述】:

我想让 SQL 在 PostgreSQL 中删除一个函数。我写了DROP FUNCTION 和来自pg_proc 的get 函数名。那不是问题。但是,如果我留下空白参数,它将不会删除该函数。

我查看了手册并写了然后我必须用它的参数来识别函数以删除它,例如DROP FUNCTION some_func(text,integer) 而不仅仅是DROP FUNCTION some_func

在哪里可以找到参数?在pg_proc 表中的函数行中,没有参数。那么如何让 SQL 删除函数呢?

【问题讨论】:

  • 通过pgAdmin查看函数
  • \df namepsql
  • @John:这个问题有答案还是未解决?

标签: postgresql function ddl catalog


【解决方案1】:

Postgres 有一个专门的功能用于此目的。随 Postgres 8.4 引入。 The manual:

pg_get_function_identity_arguments(func_oid) ... 获取参数列表以识别函数(无默认值)...

pg_get_function_identity_arguments 返回参数列表 识别功能所必需的,以它需要出现的形式 例如,在ALTER FUNCTION 内。此表单省略了默认值。

使用它(以及 format(),Postgres 9.1 引入),以下查询生成 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 已更改。 proisaggprokind 取代,添加了真正的存储过程。你需要适应。见:

返回:

                  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;

【讨论】:

  • .... 这就是我喜欢 SO 的原因。使用 Pg 大约 4 年,我从来不知道。甜蜜。
  • 非常感谢,这正是我要找的。太好了!
【解决方案2】:

使用pgadminIII直接访问函数列表并右键单击它然后选择delete

【讨论】:

    【解决方案3】:

    在 Postgres 10 中,您可以在不知道参数列表的情况下删除函数,只要它在其模式中是唯一的。

    drop function if exists some_func;
    

    See the docs.

    当然,如果你已经重载了函数(或者试图删除多个模式),你仍然需要上面的答案。

    【讨论】:

      【解决方案4】:

      如果您正在使用旧的以前版本的 postgres,其中 pg_get_function_identity_arguments(func_oid) 不存在,我创建自己的函数从函数中获取参数,您只需要传递函数的 oid,您需要将以下功能部署到您的 postgres 数据库。

      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)"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-08
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2018-07-26
        • 2020-04-08
        • 1970-01-01
        相关资源
        最近更新 更多