PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Variáveis ​​para identificadores dentro de IF EXISTS em uma função 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;

Pontos principais


  • linha é uma palavra reservada no padrão SQL. Seu uso é permitido no Postgres, mas ainda é imprudente. Eu costumo acrescentar a variável psql com um sublinhado _ para evitar conflitos de nomenclatura.

  • Você não seleciona a linha inteira de qualquer forma, apenas o nome da tabela neste exemplo. Melhor usar uma variável do tipo regclass , evitando assim a injeção de SQL por meio de nomes de tabelas ilegais automaticamente. Detalhes nesta resposta relacionada:
    Nome da tabela como parâmetro de função do PostgreSQL

  • Você não precisa de LIMIT em um EXISTS expressão, que verifica apenas a existência de qualquer linhas. E você não precisa de colunas de destino significativas pelo mesmo motivo. Basta escrever SELECT 1 ou SELECT * ou algo .

  • Você precisa de SQL dinâmico para consultas com identificadores de variáveis. O SQL simples não permite isso. Ou seja:construa uma string de consulta e EXECUTE isto. Detalhes nesta resposta intimamente relacionada:
    SQL dinâmico (EXECUTE) como condição para instrução IF

  • O mesmo vale para um DROP declaração, se você quiser executá-lo. Eu adicionei um comentário.