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;
Points majeurs
-
row
est un mot réservé dans la norme SQL. Son utilisation est autorisée dans Postgres, mais c'est toujours imprudent. Je prends l'habitude de préfixer la variable psql avec un trait de soulignement_
pour éviter tout conflit de nom. -
Vous ne sélectionnez pas toute la ligne de toute façon, juste le nom de la table dans cet exemple. Utilisez de préférence une variable de type
regclass
, évitant ainsi automatiquement l'injection SQL par le biais de noms de table illégaux. Détails dans cette réponse connexe :
Nom de table en tant que paramètre de fonction PostgreSQL -
Vous n'avez pas besoin de
LIMIT
dans unEXISTS
expression, qui ne vérifie que l'existence de any Lignes. Et vous n'avez pas besoin de colonnes cibles significatives pour la même raison. Écrivez simplementSELECT 1
ouSELECT *
ou quelque chose . -
Vous avez besoin de SQL dynamique pour les requêtes avec des identifiants de variable. Le SQL brut ne le permet pas. C'est-à-dire :créez une chaîne de requête et
EXECUTE
ce. Détails dans cette réponse étroitement liée :
SQL dynamique (EXECUTE) comme condition pour l'instruction IF -
Il en est de même pour un
DROP
déclaration, si vous voulez l'exécuter. J'ai ajouté un commentaire.