web-dev-qa-db-ja.com

すべての関数をPostgreSQLにドロップする方法は?

現在、クエリを使用してコマンドをテキストファイルで取得する必要があります。次に、それらから二重引用符を削除します。そして最後に、そのファイルをpsqlシェルで実行します。

PostgreSQLのすべての関数を削除するにはどうすればよいですかシングルステップで

6
Sarit

特定のスキーマ内のすべての関数(集計を含む)を削除するには(これに注意してください!):

Postgres 11の場合:- Procedures が追加されました-システムカタログpg_proc若干変更:prokindproisaggproiswindowを置き換え、さらにタグfunctionsと新しいprocedures)をタグ付けします。

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 only selected 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$  LANGUAGE plpgsql;

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$  LANGUAGE plpgsql;

このコンテキストでは、スキーマ名は大文字と小文字が区別されます。
もちろん、必要な特権が必要です。

CASCADEmehmetの例のように を追加することもできますが、関数だけでなく、依存するオブジェクトも再帰的に削除されます。それをさらに危険にします。自分が何をしているかを正確に理解している...

関連、説明付き:

11

私はいくつかのケースで上記のアーウィンの答えを修正しなければなりませんでした:

1)トリガーしてエラーとなったスキーマに集計関数がある場合。 2)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;
4
mehmet