CREATE OR REPLACE FUNCTION drop_now()
RETURNS void AS
$BODY$
DECLARE
row record;
BEGIN
RAISE INFO 'in';
FOR row IN
select relname from pg_stat_user_tables
WHERE schemaname='public' AND relname LIKE '%test%'
LOOP
IF EXISTS(SELECT row.relname.tm FROM row.relname
WHERE row.relname.tm < current_timestamp - INTERVAL '90 minutes'
LIMIT 1)
THEN
-- EXECUTE 'DROP TABLE ' || quote_ident(row.relname);
RAISE INFO 'Dropped table: %', quote_ident(row.relname);
END IF;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
你能告诉我如何在
SELECT
里面使用变量吗?目前,IF EXISTS
和row.relname.tm
按字面意思处理,这不是我想要的。CREATE OR REPLACE FUNCTION drop_now()
RETURNS void
LANGUAGE plpgsql 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$;
是标准 SQL 中的
保留字。 Postgres 中允许使用它,但仍然不明智。我喜欢在 PL/pgsql 变量前面加上下划线
row
以避免命名冲突。无论如何,您都不会选择整个行,仅选择本示例中的表名称。最好使用 _
类型的变量,从而避免隐式通过非法表名进行 SQL 注入。参见:
regclass
表达式中不需要
LIMIT
,该表达式仅检查 any行是否存在。另外,您可以将
EXISTS
列表留空。参见:
动态 SQL 来进行带有变量标识符的查询。普通 SQL 不允许这样做。即:构建一个查询字符串并 SELECT
它。参见:
EXECUTE
语句,情况也是如此。我添加了评论。