2009-08-28 6 views
65

Ich möchte in der Lage sein, eine Verbindung zu einer PostgreSQL-Datenbank herzustellen und alle Funktionen für ein bestimmtes Schema zu finden.Wie kann ich eine Liste aller Funktionen erhalten, die in der Datenbank eines bestimmten Schemas in PostgreSQL gespeichert sind?

Mein Gedanke war, dass ich eine Anfrage an pg_catalog oder information_schema stellen und eine Liste aller Funktionen bekommen konnte, aber ich kann nicht herausfinden, wo die Namen und Parameter gespeichert sind. Ich suche nach einer Abfrage, die mir den Funktionsnamen und die Parametertypen gibt, die er benötigt (und in welcher Reihenfolge er sie annimmt).

Gibt es eine Möglichkeit, dies zu tun?

Antwort

48

Nach einiger Suche konnte ich die information_schema.routines Tabelle und die information_schema.parameters Tabellen finden. Mit diesen kann man eine Abfrage für diesen Zweck erstellen. LEFT JOIN anstelle von JOIN ist notwendig, um Funktionen ohne Parameter zu erhalten.

SELECT routines.routine_name, parameters.data_type, parameters.ordinal_position 
FROM information_schema.routines 
    LEFT JOIN information_schema.parameters ON routines.specific_name=parameters.specific_name 
WHERE routines.specific_schema='my_specified_schema_name' 
ORDER BY routines.routine_name, parameters.ordinal_position; 
+2

Sie finden 'oidvectortypes' auch sehr nützlich. Siehe neue Antwort: http://StackOverflow.com/a/24034604/398670 –

+0

Der obige Code zeigt nicht alle Funktionen. Sie benötigen einen LINKEN JOIN anstelle von JOIN, um auch Funktionen ohne Eingabeparameter anzuzeigen. – David

93
\df <schema>.* 

in psql gibt die notwendigen Informationen.

Um die intern verwendete Abfrage anzuzeigen, stellen Sie eine Verbindung mit einer Datenbank mit psql her und stellen Sie eine zusätzliche Option "-E" (oder "--echo-hidden") bereit und führen Sie den obigen Befehl aus.

+1

Können Sie einfügen, was diese Abfrage ist? –

+2

sollte dies der Einfachheit halber akzeptiert werden. –

+0

SELECT n.nspname als "Schema", p.proname als "Name", pg_catalog.pg_get_function_result (p.oid) als "Ergebnisdatentyp", pg_catalog.pg_get_function_arguments (p.oid) als "Argument-Datentypen" , CASE WENN p.proisagg THEN 'agg' WENN p.proiswindow THEN 'Fenster' WHEN p.prorettype = 'pg_catalog.trigger' :: pg_catalog.regtype THEN 'Trigger' ELSE 'normal' END als " Typ " VON pg_catalog.pg_proc p LINKEN VERBINDUNG pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname ~ '^ (public) $' ORDER BY 1, 2, 4; Oben wird die Abfrage generiert (von \ set ECHO_HIDDEN 'on'). –

3

Beispiel:

perfdb-# \df information_schema.*; 

List of functions 
     Schema  |  Name  | Result data type | Argument data types | Type 
information_schema | _pg_char_max_length | integer | typid oid, typmod integer | normal 
information_schema | _pg_char_octet_length | integer | typid oid, typmod integer | normal 
information_schema | _pg_datetime_precision| integer | typid oid, typmod integer | normal 
..... 
information_schema | _pg_numeric_scale  | integer | typid oid, typmod integer | normal 
information_schema | _pg_truetypid   | oid  | pg_attribute, pg_type  | normal 
information_schema | _pg_truetypmod  | integer | pg_attribute, pg_type  | normal 
(11 rows) 
+5

Wie ist das anders als Milens Antwort? –

+2

Dies ist keine Abfrage, es ist ein Befehl der 'psql' Postgres-Client-Schnittstelle. Dies funktioniert nur in 'psql' und ist technisch gesehen keine SQL-Abfrage. – GregT

18

Wenn jemand hier interessiert, ist, welche Abfrage von psql auf Postgres 9.1 ausgeführt wird:

SELECT n.nspname as "Schema", 
    p.proname as "Name", 
    pg_catalog.pg_get_function_result(p.oid) as "Result data type", 
    pg_catalog.pg_get_function_arguments(p.oid) as "Argument data types", 
CASE 
    WHEN p.proisagg THEN 'agg' 
    WHEN p.proiswindow THEN 'window' 
    WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger' 
    ELSE 'normal' 
END as "Type" 
FROM pg_catalog.pg_proc p 
    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace 
WHERE pg_catalog.pg_function_is_visible(p.oid) 
     AND n.nspname <> 'pg_catalog' 
     AND n.nspname <> 'information_schema' 
ORDER BY 1, 2, 4; 

Sie können psql laufen, was psql läuft für einen Backslash Befehl erhalten mit der -E Flagge.

16

Es gibt eine praktische Funktion, oidvectortypes, die das viel einfacher macht.

SELECT format('%I.%I(%s)', ns.nspname, p.proname, oidvectortypes(p.proargtypes)) 
FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid) 
WHERE ns.nspname = 'my_namespace'; 

Credit Leo Hsu and Regina Obe at Postgres Online für oidvectortypes Hinweis. Ich habe zuvor ähnliche Funktionen geschrieben, aber komplexe verschachtelte Ausdrücke verwendet, für die diese Funktion nicht mehr benötigt wird.

See related answer.


(edit in 2016)

Fasst typischen Bericht Optionen:

-- Compact: 
SELECT format('%I.%I(%s)', ns.nspname, p.proname, oidvectortypes(p.proargtypes)) 

-- With result data type: 
SELECT format(
     '%I.%I(%s)=%s', 
     ns.nspname, p.proname, oidvectortypes(p.proargtypes), 
     pg_get_function_result(p.oid) 
) 

-- With complete argument description: 
SELECT format('%I.%I(%s)', ns.nspname, p.proname, pg_get_function_arguments(p.oid)) 

-- ... and mixing it. 

-- All with the same FROM clause: 
FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid) 
WHERE ns.nspname = 'my_namespace'; 

HINWEIS: p.proname||'_'||p.oid AS specific_name verwenden eindeutige Namen zu erhalten, oder mit information_schema Tabellen JOIN — routines und parameters sehen bei @ RuddZwolinski's Antwort.


Die Funktion des OID (siehe   pg_catalog.pg_proc) und die der Funktion spezifischer_name (siehe   information_schema.routines) die wichtigsten Bezugsmöglichkeiten auf Funktionen sind. Unten finden Sie einige nützliche Funktionen in Berichten und anderen Kontexten.

--- --- --- --- --- 
--- Useful overloads: 

CREATE FUNCTION oidvectortypes(p_oid int) RETURNS text AS $$ 
    SELECT oidvectortypes(proargtypes) FROM pg_proc WHERE oid=$1; 
$$ LANGUAGE SQL IMMUTABLE; 

CREATE FUNCTION oidvectortypes(p_specific_name text) RETURNS text AS $$ 
    -- Extract OID from specific_name and use it in oidvectortypes(oid). 
    SELECT oidvectortypes(proargtypes) 
    FROM pg_proc WHERE oid=regexp_replace($1, '^.+?([^_]+)$', '\1')::int; 
$$ LANGUAGE SQL IMMUTABLE; 

CREATE FUNCTION pg_get_function_arguments(p_specific_name text) RETURNS text AS $$ 
    -- Extract OID from specific_name and use it in pg_get_function_arguments. 
    SELECT pg_get_function_arguments(regexp_replace($1, '^.+?([^_]+)$', '\1')::int) 
$$ LANGUAGE SQL IMMUTABLE; 

--- --- --- --- --- 
--- User customization: 

CREATE FUNCTION pg_get_function_arguments2(p_specific_name text) RETURNS text AS $$ 
    -- Example of "special layout" version. 
    SELECT trim(array_agg(op||'-'||dt)::text,'{}') 
    FROM (
     SELECT data_type::text as dt, ordinal_position as op 
     FROM information_schema.parameters 
     WHERE specific_name = p_specific_name 
     ORDER BY ordinal_position 
    ) t 
$$ LANGUAGE SQL IMMUTABLE; 
+0

Sehr schön. Vielen Dank! –

+0

Das 'proname' ist der Name, aber wie man die OID für zB bekommt. Verwenden Sie in 'pg_catalog.pg_get_function_result (oid))'? –

+1

@PeterKrauss Die 'oid' Spalte von' pg_proc'. Es ist eine versteckte Spalte. –

6

ist eine gute Idee, die Funktionen mit commun alias auf den ersten Worten für filtre Namen mit LIKE Beispiel mit öffentlichem Schema in Postgresql 9.4, genannt sicher sein, mit seinem Schema

SELECT routine_name FROM information_schema.routines WHERE routine_type='FUNCTION' AND specific_schema='public' AND routine_name LIKE 'aliasmyfunctions%'; 
10

ersetzen Führen Sie die folgende SQL-Abfrage aus, um eine Ansicht zu erstellen, in der alle Funktionen angezeigt werden:

CREATE OR REPLACE VIEW show_functions AS 
    SELECT routine_name FROM information_schema.routines 
     WHERE routine_type='FUNCTION' AND specific_schema='public'; 
+0

Dies geht zum Repository von utils. Vielen Dank – Emiliano

Verwandte Themen