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
LIMIT
in unEXISTS
espressione, che controlla solo l'esistenza di qualsiasi righe. E non hai bisogno di colonne target significative per lo stesso motivo. Scrivi semplicementeSELECT 1
oSELECT *
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
EXECUTE
esso. Dettagli in questa risposta strettamente correlata:
SQL dinamico (EXECUTE) come condizione per l'istruzione IF -
Lo stesso vale per un
DROP
istruzione, se si desidera eseguirlo. Ho aggiunto un commento.