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;
主なポイント
-
行
予約語 です。 SQL標準で。 Postgresでは使用が許可されていますが、それでも賢明ではありません。 psql変数の前にアンダースコア_
を付けるのが習慣になっています 名前の競合を避けるため。 -
行全体を選択しないでください とにかく、この例ではテーブル名だけです。タイプ
regclass
の変数を使用するのが最適です 、これにより、不正なテーブル名によるSQLインジェクションが自動的に回避されます。この関連する回答の詳細:
PostgreSQL関数パラメータとしてのテーブル名 -
LIMIT
は必要ありませんEXISTS
で anyの存在のみをチェックする式 行。また、同じ理由で意味のあるターゲット列は必要ありません。SELECT 1 コード> または
。SELECT*
または何か -
動的SQLが必要です 変数識別子を持つクエリの場合。プレーンSQLではそれができません。つまり、クエリ文字列を作成して
EXECUTE
それ。この密接に関連する回答の詳細:
IFステートメントの条件としての動的SQL(EXECUTE) -
DROP
についても同じことが言えます。 ステートメント、それを実行したい場合。コメントを追加しました。