Come posso ottenere un elenco di tutte le funzioni memorizzate nel database di un particolare schema in PostgreSQL?


135

Voglio essere in grado di connettermi a un database PostgreSQL e trovare tutte le funzioni per un particolare schema.

Pensavo di poter fare una query su pg_catalog o information_schema e ottenere un elenco di tutte le funzioni, ma non riesco a capire dove sono memorizzati i nomi e i parametri. Sto cercando una query che mi dia il nome della funzione e i tipi di parametro che richiede (e in quale ordine li accetta).

C'è un modo per fare questo?

Risposte:


191
\df <schema>.*

in psqlfornisce le informazioni necessarie.

Per vedere la query utilizzata internamente connettersi a un database con psqle fornire un'opzione " -E" (o " --echo-hidden") aggiuntiva e quindi eseguire il comando sopra.


1
Potresti incollare qual è quella query?
Rudd Zwolinski,

3
SELEZIONARE n.nspname come "Schema", p.proname come "Nome", pg_catalog.pg_get_function_result (p.oid) come "Tipo di dati risultato", pg_catalog.pg_get_function_arguments (p.oid) come "Tipi di dati dell'argomento", 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 come "Tipo" DA pg_catalog.pg_proc p LEFT JOIN pg_catalog .pg_namespace n ON n.oid = p.pronamespace DOVE n.nspname ~ '^ (public) $' ORDINA PER 1, 2, 4; Sopra è la query generata (da \ set ECHO_HIDDEN 'on').
Simon D,

90

Dopo alcune ricerche, sono stato in grado di trovare il information_schema.routinestavolo e i information_schema.parameterstavoli. Usando quelli, si può costruire una query per questo scopo. LEFT JOIN, anziché JOIN, è necessario per recuperare le funzioni senza parametri.

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
Troverai anche oidvectortypesmolto utile. Vedi la nuova risposta: stackoverflow.com/a/24034604/398670
Craig Ringer

Il codice sopra non mostrerà tutte le funzioni, è necessario un JOIN SINISTRO anziché JOIN per mostrare anche le funzioni senza parametri di input.
David,

35

Se qualcuno è interessato qui è quale query viene eseguita psqlsu Postgres 9.1:

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;

È possibile ottenere ciò che psqlviene eseguito per un comando barra rovesciata eseguendo psqlcon il -Eflag.


Ho appena trovato la tua risposta e ho provato la query su Postgres 11.5. Dice:ERROR: column p.proisagg does not exist
Christiaan Westerbeek il

Grazie per questo; le due risposte più votate non hanno mostrato la mia funzione!
machineghost

29

C'è una comoda funzione oidvectortypesche rende tutto molto più semplice.

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

Ringraziamo Leo Hsu e Regina Obe di Postgres Online per averlo sottolineato oidvectortypes. In precedenza ho scritto funzioni simili, ma ho usato espressioni nidificate complesse che questa funzione elimina dalla necessità.

Vedi la risposta correlata .


(modifica nel 2016)

Riassumendo le opzioni tipiche del rapporto:

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

AVVISO : utilizzare p.proname||'_'||p.oid AS specific_name per ottenere nomi univoci o per ISCRIVERSI alle information_schematabelle - vedere routinese parametersalla risposta di @ RuddZwolinski.


Della funzione OID (vedi  pg_catalog.pg_proc) e della funzione nome_specifico (vedi  information_schema.routines) sono le principali opzioni di riferimento alle funzioni. Di seguito, alcune funzioni utili nel reporting e in altri contesti.

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

Il pronameè il nome, ma come ottenere l'OID per, ad esempio. utilizzare in pg_catalog.pg_get_function_result(oid))?
Peter Krauss,

1
@PeterKrauss La oidcolonna di pg_proc. È una colonna nascosta.
Craig Ringer,

1
Vedi anche stackoverflow.com/a/25388031/161040 per come escludere le funzioni dipendenti dall'estensione (ad es. Funzioni di PostGIS).
Simon D,

20

Esegui sotto query SQL per creare una vista che mostrerà tutte le funzioni:

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

10

È una buona idea nominare le funzioni con alias comune sulle prime parole per filtre il nome con LIKE Esempio con schema pubblico in Postgresql 9.4, assicurati di sostituire con il suo schema

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

4

Esempio:

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
In che modo è diverso dalla risposta di Milen?
a_horse_with_no_name

3
Questa non è una query, è un comando psqldell'interfaccia client di Postgres. Funzionerà solo in psqle non è tecnicamente una query SQL.
GregT

3

Ottieni l'elenco di function_schema e function_name ...


> select n.nspname as function_schema,
> 
> p.proname as function_name
> 
> from pg_proc p
> 
> left join pg_namespace n on p.pronamespace = n.oid
> 
> where n.nspname not in ('pg_catalog', 'information_schema')
> 
> order by function_schema, function_name;

2

Questa funzione restituisce tutte le routine definite dall'utente nel database corrente.

SELECT pg_get_functiondef(p.oid) FROM pg_proc p
INNER JOIN pg_namespace ns ON p.pronamespace = ns.oid
WHERE ns.nspname = 'public';
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.