sql >> Base de Datos >  >> RDS >> PostgreSQL

Variables para identificadores dentro de SI EXISTE en una función 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;

Puntos principales

  • row es una palabra reservada en el estándar SQL. Su uso está permitido en Postgres, pero sigue siendo imprudente. Tengo el hábito de anteponer la variable psql con un guión bajo _ para evitar conflictos de nombres.

  • No seleccionas la fila completa de todos modos, solo el nombre de la tabla en este ejemplo. Mejor use una variable de tipo regclass , evitando así la inyección de SQL a través de nombres de tablas ilegales automáticamente. Detalles en esta respuesta relacionada:
    Nombre de tabla como parámetro de función de PostgreSQL

  • No necesitas LIMIT en un EXISTS expresión, que solo comprueba la existencia de any filas Y no necesita columnas de destino significativas por la misma razón. Simplemente escriba SELECT 1 o SELECT * o algo .

  • Necesita SQL dinámico para consultas con identificadores de variables. SQL simple no permite eso. Es decir:construye una cadena de consulta y EXECUTE eso. Detalles en esta respuesta estrechamente relacionada:
    SQL dinámico (EJECUTAR) como condición para la declaración IF

  • Lo mismo es cierto para un DROP declaración, en caso de que desee ejecutarlo. Agregué un comentario.