2012-08-26 11 views
14

Ich möchte, dass SQL eine Funktion in PostgreSQL löscht. Ich schreibe DROP FUNCTION und einen Funktionsnamen von pg_proc. Das ist kein Problem. Wenn ich jedoch leere Parameter belasse, wird die Funktion nicht gelöscht.So erhalten Sie Funktionsparameterlisten (damit ich eine Funktion löschen kann)

Ich habe das Handbuch überprüft und dort geschrieben, dann muss ich die Funktion mit ihren Parametern identifizieren, um sie fallen zu lassen, zB DROP FUNCTION some_func(text,integer) nicht nur DROP FUNCTION some_func.

Wo finde ich die Parameter? In der Zeile der Funktion in der Tabelle pg_proc gibt es keine Parameter. Wie kann ich die SQL-Funktion dazu bringen, die Funktion zu löschen?

+2

Schauen Sie sich die Funktion über pgAdmin an. –

+2

'\ df name' innerhalb [' psql'] (http: //www.postgresql.org/docs/aktuell/statisch/app-psql.html). –

Antwort

24

Postgres hat eine dedizierte Funktion für diesen Zweck. Einführung in Postgres 8.4. The manual:

pg_get_function_identity_arguments(func_oid) ... erhalten Argumentliste eine Funktion (ohne Standardwerte) zu identifizieren ...

pg_get_function_identity_arguments kehrt die Argumentliste notwendig, eine Funktion, in der Form zu identifizieren, es müssten zum Beispiel in ALTER FUNCTION erscheinen. Dieses Formular enthält keine Standardwerte.

dass Verwendung (und format() mit Postgres eingeführt 9.1), die folgende Abfrage generiert DDL-Anweisungen Funktionen fallen zu Ihrem Suchbegriff:

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; 

Returns:

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

vier gefunden Übereinstimmungen im Beispiel, da dblink overloaded functions verwendet.
Führen Sie DROP Anweisungen selektiv aus!

Alternativ, können Sie die bequeme Umwandlung in den object identifier type regprocedure verwenden, die eine komplette Funktionssignatur einschließlich Argumenttypen zurückgibt:

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

.... und deshalb liebe ich SO. Ich benutze Pg für ungefähr 4 Jahre und ich wusste nie darüber. Süss. –

+0

Vielen Dank, das ist genau das, was ich suche. Groß! – John

1

Verwendung pgAdminIII und direktem Zugang zur Funktionsliste und rechts dann klicken wählen löschen enter image description here

0

Wenn Sie an einer alten früheren Version von Postgres arbeiten, für die pg_get_function_identity_arguments (func_oid) nicht existiert, erstelle ich meine eigene Funktion get den Parameter Ters von der Funktion, müssen Sie nur die oid für die Funktion übergeben, müssen Sie die Funktion unten zu Ihrer postgres db bereitstellen.

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 ; 

Die Funktion unter den Funktionsnamen und Parameter aufzulisten, die Schemanamen ändern, wenn Sie Funktion unter einem anderen Schema erhalten mögen, ich bin Öffentlichkeit zum Beispiel mit

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' 

werden Sie das Ergebnis wie unter

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