sql >> Databasteknik >  >> RDS >> PostgreSQL

Variabler för identifierare inuti IF FINNS i en plpgsql-funktion

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;

Huvudpunkter

  • rad är ett reserverat ord i SQL-standarden. Det är tillåtet att använda det i Postgres, men det är fortfarande oklokt. Jag gör det till en vana att lägga till psql-variabeln med ett understreck _ för att undvika namnkonflikter.

  • Du väljer inte hela raden hur som helst, bara tabellnamnet i det här exemplet. Använd bäst en variabel av typen regclass , och undviker därigenom SQL-injektion i form av olagliga tabellnamn automatiskt. Detaljer i detta relaterade svar:
    Tabellnamn som en PostgreSQL-funktionsparameter

  • Du behöver inte LIMIT i en FINNS uttryck, som endast kontrollerar förekomsten av någon rader. Och du behöver inte meningsfulla målkolumner av samma anledning. Skriv bara VÄLJ 1 eller VÄLJ * eller något .

  • Du behöver dynamisk SQL för frågor med variabelidentifierare. Vanlig SQL tillåter inte det. Dvs:bygg en frågesträng och EXECUTE Det. Detaljer i detta närbesläktade svar:
    Dynamisk SQL (EXECUTE) som villkor för IF-sats

  • Detsamma gäller för en DROP uttalande, om du vill köra det. Jag lade till en kommentar.



  1. Hur lägger jag till mer än en rad med Zend_Db?

  2. MySQL DROP INDEX

  3. Primärnyckel (ID) har inte hämtats (?) från databasen med OpenJPA

  4. Är mysql_real_escape_string() nödvändigt när du använder förberedda satser?