web-dev-qa-db-fra.com

Comment puis-je obtenir une liste de toutes les fonctions stockées dans la base de données d'un schéma particulier dans PostgreSQL?

Je veux pouvoir me connecter à une base de données PostgreSQL et trouver toutes les fonctions d'un schéma particulier.

Mon idée était que je pouvais interroger pg_catalog ou information_schema et obtenir une liste de toutes les fonctions, mais je ne peux pas savoir où les noms et les paramètres sont stockés. Je cherche une requête qui me donnera le nom de la fonction et les types de paramètres requis (et l'ordre dans lequel ils sont pris).

Y a-t-il un moyen de faire cela?

108
Rudd Zwolinski

Après quelques recherches, j'ai pu trouver le information_schema.routines table et le information_schema.parameters tables. En utilisant ceux-ci, on peut construire une requête à cette fin. LEFT JOIN, au lieu de JOIN, est nécessaire pour récupérer des fonctions sans paramètres.

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;
69
Rudd Zwolinski
\df <schema>.*

in psql donne les informations nécessaires.

Pour voir la requête utilisée en interne, connectez-vous à une base de données avec psql et fournissez un extra "-E" (ou "--echo-hidden "), puis exécutez la commande ci-dessus.

158
Milen A. Radev

Si quelqu'un est intéressé, voici quelle requête est exécutée par psql sur 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;

Vous pouvez obtenir ce que psql exécute pour une commande de barre oblique inverse en exécutant psql avec le -E drapeau.

29
jb.

Il y a une fonction pratique, oidvectortypes, qui facilite beaucoup cela.

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

Nous remercions Leo Hsu et Regina Obe de Postgres Online pour avoir signalé oidvectortypes. J'avais écrit des fonctions similaires auparavant, mais j'utilisais des expressions complexes imbriquées pour lesquelles cette fonction supprime la nécessité.

Voir la réponse associée .


(éditer en 2016)

Résumé des options de rapport typiques:

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

[~ # ~] avis [~ # ~] : utilisez p.proname||'_'||p.oid AS specific_name pour obtenir des noms uniques, ou pour JOIN avec information_schema tables - voir routines et parameters à la réponse de @ RuddZwolinski.


La fonction [~ # ~] oid [~ # ~] (voir pg_catalog.pg_proc) et la fonction nom_spécifique (voir information_schema.routines) sont les principales options de référence pour les fonctions. Ci-dessous, quelques fonctions utiles dans les rapports et dans d'autres contextes.

--- --- --- --- ---
--- 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;
25
Craig Ringer

Exécutez la requête SQL ci-dessous pour créer une vue qui affichera toutes les fonctions:

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

C'est une bonne idée de nommer les fonctions avec alias commun sur les premiers mots pour filtrer le nom avec LIKE Exemple avec schéma public dans Postgresql 9.4, assurez-vous de le remplacer par son schéma

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

Exemple:

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)
4
Ritu