删除postgres中共享相同前缀的所有表

时间:2014-12-22 21:44:27

标签: sql postgresql plpgsql dynamic-sql

我想使用一个sql命令/查询从同一个数据库中删除所有共享相同前缀(' supenh_agk')的表。

3 个答案:

答案 0 :(得分:24)

要在 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;
END LOOP;
END
$do$;

这包括来自当前用户有权访问的所有模式的表。为安全起见,我排除了系统架构。

如果您没有正确转义标识符,则任何需要双引号的非标准identifier的代码都会失败。
另外,您冒着允许 SQL注入的风险。必须在动态代码中清理所有用户输入 - 包括可能由用户提供的标识符。

潜在危险!所有这些桌子都被丢弃了。我建在一个安全的地方。在实际执行之前检查生成的语句:comment RAISE并取消注释EXECUTE

密切相关:

或者您可以在目录表pg_class上构建,目录表How to check if a table exists in a given schema也提供表的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注入?

  • {{3}}

答案 1 :(得分:6)

假设前缀为'sales _'

第1步:获取具有该前缀的所有表名

SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'sales_%';

第2步:点击“以CSV格式下载”按钮。

第3步:在编辑器中打开文件,将“sales _ 替换为,sales         和带空格

第4步: DROP TABLE sales_regist, sales_name, sales_info, sales_somthing;

答案 2 :(得分:3)

这是sql server命令,你可以尝试这个,它是否在postgres中工作。 此查询将生成用于删除的SQL脚本

SELECT 'DROP TABLE "' || TABLE_NAME || '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

<强> [编辑]

begin
    for arow in
      SELECT 'DROP TABLE "' || TABLE_NAME || '"' as col1
      FROM INFORMATION_SCHEMA.TABLES 
      WHERE TABLE_NAME LIKE '[prefix]%'
    LOOP
   --RAISE NOTICE '%',    
    EXECUTE 'DROP TABLE ' || arow ;
END LOOP;
  end;