2012-08-26 18 views
14

Chcę, aby SQL rzucił funkcję w PostgreSQL. Piszę DROP FUNCTION i nazwę funkcji get od pg_proc. To nie jest problem. Jednak jeśli zostawiam puste parametry, nie upuszczę funkcji.Jak uzyskać listę parametrów funkcji (aby można było usunąć funkcję)

Sprawdziłem instrukcję i tam jest napisane, że muszę zidentyfikować funkcję z jej parametrami, aby ją upuścić, np. DROP FUNCTION some_func(text,integer) nie tylko DROP FUNCTION some_func.

Gdzie mogę znaleźć parametry? W wierszu funkcji w tabeli pg_proc nie ma parametrów. Więc jak mogę uzyskać SQL, aby usunąć tę funkcję?

+2

Sprawdź funkcję za pomocą pgAdmin. –

+2

'\ df name' inside [' psql'] (http: //www.postgresql.org/docs/current/static/app-psql.html). –

Odpowiedz

24

Postgres ma dedykowaną funkcję do tego celu. Wprowadzono za pomocą Postgres 8.4. The manual:

pg_get_function_identity_arguments(func_oid) ... dostać listę argumentów do identyfikacji funkcji (bez wartości domyślnych) ...

pg_get_function_identity_arguments zwraca listę argumentów niezbędne do określenia funkcji w postaci musiałaby pojawiać się na przykład w obrębie ALTER FUNCTION. Ta forma pomija wartości domyślne.

Korzystanie że (i format(), wprowadzony z PostgreSQL 9.1), następujące zapytanie generuje DDL do spadku funkcji spełniających warunki wyszukiwania:

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; 

Powroty:

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

Znaleziono cztery dopasowuje w przykładzie, ponieważ dblink używa overloaded functions.
Wykonywanie instrukcji DROP wybiórczo!

Alternatywnie, można skorzystać z wygodnego obsady do object identifier type regprocedure która zwraca pełną sygnaturę funkcji w tym rodzaju Argument:

-- 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; 
+2

.... i dlatego kocham SO. Używanie Pg przez około 4 lata i nigdy o tym nie wiedziałem. Słodkie. –

+0

Wielkie dzięki, właśnie tego szukam. Wspaniały! – John

1

użytku pgadminIII i bezpośredni dostęp do listy funkcji i kliknij prawym przyciskiem myszy, a następnie wybierz usuwać enter image description here

0

Jeśli pracujesz na starym poprzedniej wersji PostgreSQL, dla których pg_get_function_identity_arguments (func_oid) nie istnieje, tworzę własne funkcja uzyskać Param z funkcji, wystarczy przekazać oid do funkcji, musisz wdrożyć funkcję poniżej do swojego postgres db.

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 ; 

Funkcja poniżej listy nazwę funkcji i parametrów, zmienić nazwę schematu, jeśli chcesz uzyskać funkcję w ramach innego schematu używam publicznej np

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' 

Będziesz roku wynik jak poniżej:

1 "public.getfunctionparameter(integer,text)" 
2 "public.getfunctionparameter(oid)"