如何删除我在 PostgreSQL 中的所有函数?

Sar*_*rit 9 postgresql dynamic-sql functions

现在我必须使用查询来获取文本文件中的命令。然后从中删除双引号。最后,在 psql shell 中运行该文件。

如何一步删除 PostgreSQL中的所有函数?

Erw*_*ter 14

要删除给定模式中的所有函数(包括聚合)(注意这一点!):

Postgres 11 或更高版本

  • 程序已添加。
  • 系统目录pg_proc略有变化:prokind替换proisaggproiswindow- 以及标记功能和新程序
DO
$do$
DECLARE
   _sql text;
BEGIN
   SELECT INTO _sql
          string_agg(format('DROP %s %s;'
                          , CASE prokind
                              WHEN 'f' THEN 'FUNCTION'
                              WHEN 'a' THEN 'AGGREGATE'
                              WHEN 'p' THEN 'PROCEDURE'
                              WHEN 'w' THEN 'FUNCTION'  -- window function (rarely applicable)
                              -- ELSE NULL              -- not possible in pg 11
                            END
                          , oid::regprocedure)
                   , E'\n')
   FROM   pg_proc
   WHERE  pronamespace = 'public'::regnamespace  -- schema name here!
   -- AND    prokind = ANY ('{f,a,p,w}')         -- optionally filter kinds
   ;

   IF _sql IS NOT NULL THEN
      RAISE NOTICE '%', _sql;  -- debug / check first
      -- EXECUTE _sql;         -- uncomment payload once you are sure
   ELSE 
      RAISE NOTICE 'No fuctions found in schema %', quote_ident(_schema);
   END IF;
END
$do$;
Run Code Online (Sandbox Code Playgroud)

在此上下文中,架构名称区分大小写。
执行角色当然需要拥有必要的权限。

您可能会添加CASCADE 像 mehmet 演示的那样,但这也会递归地删除依赖对象——而不仅仅是函数。让它变得更加危险。你最好清楚地知道你在做什么。

相关,有更多解释:

Postgres 10 或以上

DO
$do$
DECLARE
   _sql text;
BEGIN
   SELECT INTO _sql
          string_agg(format('DROP %s %s;'
                          , CASE WHEN proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END
                          , oid::regprocedure)
                   , E'\n')
   FROM   pg_proc
   WHERE  pronamespace = 'public'::regnamespace;  -- schema name here!

   IF _sql IS NOT NULL THEN
      RAISE NOTICE '%', _sql;  -- debug / check first
      -- EXECUTE _sql;         -- uncomment payload once you are sure
   ELSE 
      RAISE NOTICE 'No fuctions found in schema %', quote_ident(_schema);
   END IF;
END
$do$;
Run Code Online (Sandbox Code Playgroud)


meh*_*met 5

对于以下几种情况,我不得不修改上面的 Erwin 的回答:

1) 如果架构中有一个聚合函数触发并出错。2)如果你想在两个模式中删除函数,而删除的函数在第一个,它也被删除了。3) 如果功能相互依赖。使用级联强制删除。

这里是:

create or replace function data.delete_all_functions(schema_in text)
    returns void as
$$
declare
    qry text;

begin
    select into qry string_agg(
       format(
          case when proname = 'delete_all_functions' then '-- %s;' -- don't delete self
               when proisagg then 'drop aggregate if exists %s cascade;'
               else 'drop function if exists %s cascade;'
             end,
          oid :: regprocedure
          ),
       E'\n'
        )
    from pg_proc
    where pronamespace = schema_in :: regnamespace;

    if qry is not null then
        execute qry;
        raise notice 'deleted all functions in schema: %', schema_in;
    else
        raise notice 'no functions to delete in schema: %', schema_in;
    end if;
end
$$
language plpgsql;
Run Code Online (Sandbox Code Playgroud)