PostgreSQL: comment lister toutes les fonctions stockées qui accèdent à une table spécifique

13

Introduction:

Base de données PostgreSQL avec plusieurs centaines de fonctions stockées, y compris obsolètes, non utilisées, etc.

Problème

J'ai besoin de découvrir toutes les fonctions stockées qui ont une relation avec la table X - car je veux changer la structure de la table. Certains d'entre eux peuvent ne pas être utilisés, je ne peux donc pas le faire simplement en parcourant le code.

La solution que j'ai ATM exécute la \df+sortie psql et grepping, mais je préférerais une solution plus semblable à une base de données, c'est-à-dire en utilisant un schéma d'information. Ce sera certainement une tâche répétitive et j'aimerais que ce soit agréable et propre.

Aucune suggestion?

Sergey Kudriavtsev
la source

Réponses:

18

Le corps d'une fonction est simplement stocké sous forme de chaîne . Il n'y a pas de liste d'objets référencés. (C'est différent des vues, par exemple, où les liens réels vers les tables référencées sont enregistrés.)

Cette requête pour Postgres 10 ou une version antérieure utilise la fonction d'informations du catalogue systèmepg_get_functiondef() pour reconstruire le CREATE FUNCTIONscript pour les fonctions pertinentes et recherche le nom de la table avec une expression régulière insensible à la casse:

SELECT n.nspname AS schema_name
     , p.proname AS function_name
     , pg_get_function_arguments(p.oid) AS args
     , pg_get_functiondef(p.oid) AS func_def
FROM   pg_proc p
JOIN   pg_namespace n ON n.oid = p.pronamespace
WHERE  NOT p.proisagg
AND    n.nspname NOT LIKE 'pg_%'
AND    n.nspname <> 'information_schema'
AND    pg_get_functiondef(p.oid) ~* '\mbig\M';

Il devrait faire l'affaire, mais ce n'est évidemment pas à l'épreuve des balles. Il peut échouer pour le SQL dynamique où le nom de la table est généré dynamiquement et il peut renvoyer n'importe quel nombre de faux positifs - en particulier si le nom de la table est un mot courant.

Les fonctions d'agrégation et toutes les fonctions des schémas système sont exclues.

\met\M marquez le début et la fin d'un mot dans l'expression régulière.

Le catalogue système pg_procmodifié dans Postgres 11. a proisaggété remplacé par prokind, de véritables procédures stockées ont été ajoutées. Vous devez vous adapter. En relation:

Erwin Brandstetter
la source
1
Oui ... ce n'est pas totalement robuste, dans le sens où il ne trouvera pas d' EXECUTEexpressions comme 'mm_'||name_parameter, et il ne s'adaptera pas correctement aux noms cités comme "my""table""ou avec le casse, mais il fera la plupart de ce que la plupart des gens voudront .
Craig Ringer
@CraigRinger: Oui, les requêtes dynamiques avec EXECUTEsont presque impossibles à couvrir. Mais le pliage du boîtier peut être recouvert au ~*lieu de ~- ou de tout autre filtrage insensible à la casse.
Erwin Brandstetter
Tant que l'opérateur n'est pas assez fou pour créer des tables nommées "MyTable"et MyTable, au moins ... et honnêtement, c'est un "bien, cela pourrait être autorisé mais ce n'est pas intelligent".
Craig Ringer
Merci d'avoir répondu! En fait, je n'utilise la construction de nom de table dynamique nulle part et tous les noms de table sont en minuscules.
Sergey Kudriavtsev
1

Cette requête est assez simple à utiliser:

SELECT proname, proargnames, prosrc FROM pg_proc WHERE prosrc ILIKE '%Text to search%';
joao victor silva de oliveira
la source