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;
Punti principali
-
rowè una parola riservata nello standard SQL. Il suo utilizzo è consentito in Postgres, ma non è ancora saggio. Ho l'abitudine di anteporre la variabile psql con un trattino basso_per evitare conflitti di denominazione. -
Non selezioni l'intera riga comunque, solo il nome della tabella in questo esempio. Utilizzare al meglio una variabile di tipo
regclass, evitando così automaticamente l'iniezione SQL tramite nomi di tabelle illegali. Dettagli in questa risposta correlata:
Nome tabella come parametro di funzione PostgreSQL -
Non hai bisogno di
LIMITin unEXISTSespressione, che controlla solo l'esistenza di qualsiasi righe. E non hai bisogno di colonne target significative per lo stesso motivo. Scrivi semplicementeSELECT 1oSELECT *o qualcosa del genere . -
Hai bisogno di SQL dinamico per le query con identificatori di variabili. Plain SQL non lo consente. Ad esempio:crea una stringa di query e
EXECUTEesso. Dettagli in questa risposta strettamente correlata:
SQL dinamico (EXECUTE) come condizione per l'istruzione IF -
Lo stesso vale per un
DROPistruzione, se si desidera eseguirlo. Ho aggiunto un commento.