DROP FUNCTION without knowing the number/type of parameters?

后端 未结 7 858
面向向阳花
面向向阳花 2020-12-01 02:20

I keep all my functions in a text file with \'CREATE OR REPLACE FUNCTION somefunction\'. So if I add or change some function I just feed the file to psql.

7条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-01 02:29

    Slightly enhanced version of Erwin's answer. Additionally supports following

    • 'like' instead of exact function name match
    • can run in 'dry-mode' and 'trace' the SQL for removing of the functions

    Code for copy/paste:

    /**
     * Removes all functions matching given function name mask
     *
     * @param p_name_mask   Mask in SQL 'like' syntax
     * @param p_opts        Combination of comma|space separated options:
     *                        trace - output SQL to be executed as 'NOTICE'
     *                        dryrun - do not execute generated SQL
     * @returns             Generated SQL 'drop functions' string
     */
    CREATE OR REPLACE FUNCTION mypg_drop_functions(IN p_name_mask text,
                                                   IN p_opts text = '')
        RETURNS text LANGUAGE plpgsql AS $$
    DECLARE
        v_trace boolean;
        v_dryrun boolean;
        v_opts text[];
        v_sql text;
    BEGIN
        if p_opts is null then
            v_trace = false;
            v_dryrun = false;
        else
            v_opts = regexp_split_to_array(p_opts, E'(\\s*,\\s*)|(\\s+)');
            v_trace = ('trace' = any(v_opts)); 
            v_dryrun = ('dry' = any(v_opts)) or ('dryrun' = any(v_opts)); 
        end if;
    
        select string_agg(format('DROP FUNCTION %s(%s);', 
            oid::regproc, pg_get_function_identity_arguments(oid)), E'\n')
        from pg_proc
        where proname like p_name_mask
        into v_sql;
    
        if v_sql is not null then
            if v_trace then
                raise notice E'\n%', v_sql;
            end if;
    
            if not v_dryrun then
                execute v_sql;
            end if;
        end if;
    
        return v_sql;
    END $$;
    
    select mypg_drop_functions('fn_dosomething_%', 'trace dryrun');
    

提交回复
热议问题