PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Variabili per gli identificatori all'interno di IF EXISTS in una funzione 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;

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 un EXISTS espressione, che controlla solo l'esistenza di qualsiasi righe. E non hai bisogno di colonne target significative per lo stesso motivo. Scrivi semplicemente SELECT 1 o SELECT * 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.