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;
Główne punkty
-
wiersz
jest słowem zarezerwowanym w standardzie SQL. Jego użycie jest dozwolone w Postgresie, ale nadal jest nierozsądne. Przyzwyczajam się do tego, aby przed zmienną psql dodawać podkreślenie_
aby uniknąć konfliktów nazw. -
Nie zaznaczasz całego wiersza w każdym razie tylko nazwa tabeli w tym przykładzie. Najlepiej użyć zmiennej typu
regclass
, dzięki czemu automatycznie unika się wstrzykiwania SQL poprzez niedozwolone nazwy tabel. Szczegóły w tej powiązanej odpowiedzi:
Nazwa tabeli jako parametr funkcji PostgreSQL -
Nie potrzebujesz
LIMIT
wISTNIEJE
wyrażenie, które sprawdza tylko istnienie dowolnego wydziwianie. Z tego samego powodu nie potrzebujesz też sensownych kolumn docelowych. Po prostu napiszSELECT 1 lub
.WYBIERZ *
czy coś -
Potrzebujesz dynamicznego SQL dla zapytań ze zmiennymi identyfikatorami. Zwykły SQL na to nie pozwala. Np.:zbuduj ciąg zapytania i
WYKONAJ
to. Szczegóły w tej ściśle powiązanej odpowiedzi:
Dynamiczny SQL (EXECUTE) jako warunek instrukcji IF -
To samo dotyczy
DROP
oświadczenie, jeśli chcesz go uruchomić. Dodałem komentarz.