PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Variables pour les identifiants à l'intérieur de IF EXISTS dans une fonction plpgsql

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 un EXISTS 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 simplement SELECT 1 ou SELECT * 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.