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 sortie \df+
Et grepping de psql, mais je préférerais une solution plus proche de la 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?
Le corps d'une fonction est simplement stocké sous la forme string. 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 plus ancien utilise la fonction fonction d'information du catalogue système pg_get_functiondef()
pour reconstruire le CREATE FUNCTION
script 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 commun.
Les fonctions d'agrégation et toutes les fonctions des schémas système sont exclues.
\m
et \M
marque le début et la fin d'un mot dans l'expression régulière.
Le catalogue système pg_proc
modifié dans Postgres 11. proisagg
a été remplacé par prokind
, de véritables procédures stockées ont été ajoutées. Vous devez vous adapter. En relation:
Cette requête est assez simple à utiliser:
SELECT proname, proargnames, prosrc FROM pg_proc WHERE prosrc ILIKE '%Text to search%';