2014-01-26 4 views
1

Чтобы восстановить мои данные из pgdump, мне нужно удалить пользовательские функции из базы данных.
Эта функция идентификации их хорошо:PostgreSQL, drop custom functions

SELECT pp.proname 
    FROM pg_proc pp 
INNER JOIN pg_namespace pn on (pp.pronamespace = pn.oid) 
INNER JOIN pg_language pl on (pp.prolang = pl.oid) 
WHERE pl.lanname NOT IN ('c','internal') 
    AND pn.nspname NOT LIKE 'pg_%' 
    AND pn.nspname <> 'information_schema'; 

Так, сразу же после того, как я слышу dynamic SQL и убедиться, что я могу использовать его с .NET Я пытаюсь применить его для этой цели.

do 
$$ 
declare 
    func_rec record; 
begin 
    for func_rec in (SELECT pp.proname as funcname 
         FROM pg_proc pp 
        INNER JOIN pg_namespace pn on (pp.pronamespace = pn.oid) 
        INNER JOIN pg_language pl on (pp.prolang = pl.oid) 
        WHERE pl.lanname NOT IN ('c','internal') 
         AND pn.nspname NOT LIKE 'pg_%' 
         AND pn.nspname <> 'information_schema') 
    loop 
    execute 'drop function '||func_rec.funcname||' cascade'; 
    end loop; 
end; 
$$ 

В то же время я обнаружил, что для функции drop я должен предоставить свои параметры команде DROP.
Вот один example подзапроса о том, как эти параметры могут быть получены:

(SELECT typname FROM pg_type WHERE oid = funcrow.proargtypes[i]) 

Теперь остается проблема, что я не знаю, как поставить те, в функциональном коде, который добавит необходимые параметры func_rec.funcname в порядке для удаления таких функций.

Итак, пожалуйста, помогите получить запрос на удаление пользовательских функций из всех функций.

ответ

1

Поскольку функции могут быть перегружены в Postgres, вам необходимо включить подпись функции в drop.

Предположим, у вас есть следующие функции:

get_answer(p1 integer); 
get_answer(p1 integer, p2 integer); 

тогда Postgres не будет знать, какой из них отказаться при использовании drop function get_answer;.

Luckly Postgres имеет функцию форматирования аргументов, чтобы их можно было использовать для этой цели: pg_get_function_identity_arguments.

Таким образом, вы должны изменить свой выбор на:

SELECT pp.proname||'('||pg_get_function_identity_arguments(pp.oid)||')' as funcname 
    FROM pg_proc pp 
INNER JOIN pg_namespace pn on (pp.pronamespace = pn.oid) 
INNER JOIN pg_language pl on (pp.prolang = pl.oid) 
WHERE pl.lanname NOT IN ('c','internal') 
    AND pn.nspname NOT LIKE 'pg_%' 
    AND pn.nspname <> 'information_schema'; 
+0

Да, в настоящее время работают точно так, как ожидалось, и хотел. От pgAdmin и от .NET тоже. Поскольку моя программа автоматически создавала эти функции при запуске (если не существует), теперь у меня снова есть чистая ситуация, чтобы ловить резервную копию с этими функциями обратно без каких-либо надежных заданий/проблем. Спасибо. –

Смежные вопросы