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 enFINNS
uttryck, som endast kontrollerar förekomsten av någon rader. Och du behöver inte meningsfulla målkolumner av samma anledning. Skriv baraVÄ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.