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;
Belangrijkste punten
-
row
is een gereserveerd woord in de SQL-standaard. Het gebruik ervan is toegestaan in Postgres, maar het is nog steeds onverstandig. Ik maak er een gewoonte van om psql-variabele vooraf te laten gaan met een onderstrepingsteken_
om eventuele naamconflicten te voorkomen. -
Je selecteert niet de hele rij hoe dan ook, alleen de tabelnaam in dit voorbeeld. Gebruik het beste een variabele van het type
regclass
, waardoor automatisch SQL-injectie door middel van illegale tabelnamen wordt vermeden. Details in dit gerelateerde antwoord:
Tabelnaam als een PostgreSQL-functieparameter -
Je hebt
LIMIT
niet nodig in eenEXISTS
expressie, die alleen controleert op het bestaan van elke rijen. En om dezelfde reden heb je geen zinvolle doelkolommen nodig. Schrijf gewoonSELECT 1
ofSELECT *
of zoiets . -
Je hebt dynamische SQL nodig voor zoekopdrachten met variabele identifiers. Plain SQL laat dat niet toe. D.w.z.:bouw een queryreeks en
EXECUTE
het. Details in dit nauw verwante antwoord:
Dynamische SQL (EXECUTE) als voorwaarde voor IF-statement -
Hetzelfde geldt voor een
DROP
statement, als u het wilt uitvoeren. Ik heb een opmerking toegevoegd.