要在one命令中执行此操作,需要在DO
语句(或函数)中使用EXECUTE
动态SQL:
DO
$do$
DECLARE
_tbl text;
BEGIN
FOR _tbl IN
SELECT quote_ident(table_schema) || '.'
|| quote_ident(table_name) -- escape identifier and schema-qualify!
FROM information_schema.tables
WHERE table_name LIKE 'prefix' || '%' -- your table name prefix
AND table_schema NOT LIKE 'pg\_%' -- exclude system schemas
LOOP
RAISE NOTICE '%',
-- EXECUTE
'DROP TABLE ' || _tbl; -- see below
END LOOP;
END
$do$;
这包括当前用户可以访问的all个模式中的表.为了安全起见,我排除了系统模式.
如果没有正确转义标识符,那么对于任何需要双引号的非标准identifier,代码都会失败
Potentially hazardous!.所有这些桌子都被永久丢弃了.我建了一个保险箱.在实际执行之前判断生成的语句:注释RAISE
并取消注释EXECUTE
.
如果任何其他对象(如视图等)依赖于某个表,则会收到一条信息性错误消息,从而取消整个事务.如果您确信所有受抚养人也可能死亡,请附上CASCADE
:
'DROP TABLE ' || _tbl || ' CASCADE;
密切相关:
Alternatively您可以在目录表pg_class
的基础上进行构建,目录表pg_class
还提供了表的oid
,并且速度更快:
...
FOR _tbl IN
SELECT c.oid::regclass::text -- escape identifier and schema-qualify!
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname NOT LIKE 'pg\_%' -- exclude system schemas
AND c.relname LIKE 'prefix' || '%' -- your table name prefix
AND c.relkind = 'r' -- only tables
...
系统目录还是信息模式?
c.oid::regclass
如何抵御SQL注入?
Or.在一个single 100 command小时内完成这一切.应该更高效一些:
DO
$do$
BEGIN
RAISE NOTICE '%', (
-- EXECUTE (
SELECT 'DROP TABLE ' || string_agg(format('%I.%I', schemaname, tablename), ', ')
-- || ' CASCADE' -- optional
FROM pg_catalog.pg_tables t
WHERE schemaname NOT LIKE 'pg\_%' -- exclude system schemas
AND tablename LIKE 'prefix' || '%' -- your table name prefix
);
END
$do$;
相关的:
使用上一个示例中方便安装的系统目录pg_tables
.为了方便起见,format()
.见: