CREATE OR REPLACE FUNCTION drop_now()
RETURNS void AS
$func$
DECLARE
_tbl regclass;
_found int;
BEGIN
FOR _tbl IN
SELECT relid
FROM pg_stat_user_tables
WHERE schemaname = 'public'
AND relname LIKE '%test%'
LOOP
EXECUTE format($f$SELECT 1 FROM %s
WHERE tm < now() - interval '90 min'$f$, _tbl);
GET DIAGNOSTICS _found = ROW_COUNT;
IF _found > 0 THEN
-- EXECUTE 'DROP TABLE ' || _tbl;
RAISE NOTICE 'Dropped table: %', _tbl;
END IF;
END LOOP;
END
$func$ LANGUAGE plpgsql;
Pontos principais
-
linha
é uma palavra reservada
no padrão SQL. Seu uso é permitido no Postgres, mas ainda é imprudente. Eu costumo acrescentar a variável psql com um sublinhado _
para evitar conflitos de nomenclatura.
-
Você não seleciona a linha inteira de qualquer forma, apenas o nome da tabela neste exemplo. Melhor usar uma variável do tipo regclass
, evitando assim a injeção de SQL por meio de nomes de tabelas ilegais automaticamente. Detalhes nesta resposta relacionada:
Nome da tabela como parâmetro de função do PostgreSQL
-
Você não precisa de LIMIT
em um EXISTS
expressão, que verifica apenas a existência de qualquer linhas. E você não precisa de colunas de destino significativas pelo mesmo motivo. Basta escrever SELECT 1 ou SELECT *
ou algo
.
-
Você precisa de SQL dinâmico para consultas com identificadores de variáveis. O SQL simples não permite isso. Ou seja:construa uma string de consulta e EXECUTE
isto. Detalhes nesta resposta intimamente relacionada:
SQL dinâmico (EXECUTE) como condição para instrução IF
-
O mesmo vale para um DROP
declaração, se você quiser executá-lo. Eu adicionei um comentário.