Ecco tre esempi di restituzione di un elenco di stored procedure che fanno riferimento a una tabella specifica in PostgreSQL.
Il information_schema.routines
Visualizza
Possiamo interrogare information_schema.routines
visualizza per vedere se una qualsiasi delle definizioni contiene il nome della tabella.
Esempio:
SELECT
routine_name,
routine_body,
routine_definition
FROM information_schema.routines
WHERE routine_type = 'PROCEDURE'
AND routine_schema = 'public'
AND routine_definition ILIKE '%artists%';
In questo esempio, ho verificato se una qualsiasi delle stored procedure avesse il testo artists
nella loro definizione.
Il ILIKE
l'operatore rende la corrispondenza senza distinzione tra maiuscole e minuscole in base alla locale attiva. Questa è un'estensione PostgreSQL e non fa parte dello standard SQL. Per una corrispondenza con distinzione tra maiuscole e minuscole, usa LIKE
.
Si noti che non è perfetto, nel senso che potrebbe restituire falsi positivi se il testo è nella procedura, ma non è una tabella. Per mitigare questo rischio, potresti forse affinare i criteri di filtro.
Il pg_proc
Catalogo
Il pg_catalog.pg_proc
Il catalogo memorizza informazioni su funzioni, procedure, funzioni aggregate e funzioni della finestra. Possiamo quindi interrogare in questo modo:
SELECT
n.nspname AS schema_name,
p.proname AS function_name,
pg_get_function_arguments(p.oid) AS arguments,
p.prosrc AS definition
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE p.prokind = 'p'
AND n.nspname = 'public'
AND p.prosrc ILIKE '%artists%';
In questo caso, ci uniamo al catalogo con lo pg_catalog.pg_namespace
catalog per filtrare i risultati alle sole procedure con il public
spazio dei nomi.
In alternativa possiamo usare pg_get_functiondef()
funzione per ottenere la definizione. Questa funzione ricostruisce effettivamente il comando di creazione per la procedura memorizzata. È una ricostruzione decompilata, non il testo originale del comando. Ciò si traduce in una CREATE OR REPLACE PROCEDURE
istruzione per la procedura memorizzata.
Esempio:
SELECT
n.nspname AS schema_name,
p.proname AS function_name,
pg_get_function_arguments(p.oid) AS arguments,
pg_get_functiondef(p.oid) AS definition
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE p.prokind = 'p'
AND n.nspname = 'public'
AND p.prosrc ILIKE '%artists%';
Ottieni la riga specifica che fa riferimento alla tabella
Possiamo modificare la nostra query per includere il numero di riga che fa riferimento alla tabella:
SELECT *
FROM (
SELECT
proname AS stored_procedure,
row_number() OVER (partition by proname) AS line_number,
textline
FROM (
SELECT
proname,
unnest(string_to_array(prosrc, chr(10))) AS textline
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE nspname = 'public'
AND prosrc ILIKE '%artists%'
) lines
) x
WHERE textline ILIKE '%artists%';
Questo esempio si basa su una risposta Stack Overflow di Klin.