PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

3 maneiras de listar todos os procedimentos armazenados que fazem referência a uma tabela no PostgreSQL


Aqui estão três exemplos de como retornar uma lista de procedimentos armazenados que fazem referência a uma tabela específica no PostgreSQL.

O information_schema.routines Visualizar


Podemos consultar o information_schema.routines view para ver se alguma das definições contém o nome da tabela.

Exemplo:
SELECT
    routine_name,
    routine_body,
    routine_definition
FROM information_schema.routines
WHERE routine_type = 'PROCEDURE'
AND routine_schema = 'public'
AND routine_definition ILIKE '%artists%';

Neste exemplo, verifiquei se algum dos procedimentos armazenados tinha o texto artists em sua definição.

O ILIKE O operador faz a correspondência não diferenciar maiúsculas de minúsculas de acordo com a localidade ativa. Esta é uma extensão do PostgreSQL e não faz parte do padrão SQL. Para uma correspondência que diferencia maiúsculas de minúsculas, use LIKE .

Observe que não é perfeito, no sentido de que pode retornar falsos positivos se o texto estiver no procedimento, mas não for uma tabela. Para mitigar esse risco, talvez você possa refinar os critérios de filtro.

O pg_proc Catálogo


O pg_catalog.pg_proc catalog armazena informações sobre funções, procedimentos, funções agregadas e funções de janela. Podemos, portanto, consultar assim:
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%';

Neste caso, juntamos o catálogo com o pg_catalog.pg_namespace catalog para filtrar os resultados apenas para procedimentos com o public namespace.

Alternativamente, podemos usar o pg_get_functiondef() função para obter a definição. Essa função realmente reconstrói o comando de criação para o procedimento armazenado. É uma reconstrução descompilada, não o texto original do comando. Isso resulta em um CREATE OR REPLACE PROCEDURE instrução para o procedimento armazenado.

Exemplo:
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%';

Obter a linha específica que faz referência à tabela


Podemos modificar nossa consulta para incluir o número da linha que faz referência à tabela:
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%';

Este exemplo é baseado em uma resposta do Stack Overflow do Klin.