【问题标题】:How to drop multiple tables in PostgreSQL using a wildcard如何使用通配符删除 PostgreSQL 中的多个表
【发布时间】:2011-05-11 06:28:16
【问题描述】:

使用分区时,通常需要一次删除所有分区。

然而

DROP TABLE tablename*

不起作用。 (不考虑通配符)。

有没有一种优雅的(阅读:容易记住)方法在一个带有通配符的命令中删除多个表?

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    使用逗号分隔列表:

    DROP TABLE foo, bar, baz;
    

    如果你真的需要一把足枪,这个就可以了:

    CREATE OR REPLACE FUNCTION footgun(IN _schema TEXT, IN _parttionbase TEXT) 
    RETURNS void 
    LANGUAGE plpgsql
    AS
    $$
    DECLARE
        row     record;
    BEGIN
        FOR row IN 
            SELECT
                table_schema,
                table_name
            FROM
                information_schema.tables
            WHERE
                table_type = 'BASE TABLE'
            AND
                table_schema = _schema
            AND
                table_name ILIKE (_parttionbase || '%')
        LOOP
            EXECUTE 'DROP TABLE ' || quote_ident(row.table_schema) || '.' || quote_ident(row.table_name) || ' CASCADE ';
            RAISE INFO 'Dropped table: %', quote_ident(row.table_schema) || '.' || quote_ident(row.table_name);
        END LOOP;
    END;
    $$;
    
    SELECT footgun('public', 'tablename');
    

    【讨论】:

    • 感谢您的回答!逗号分隔的列表非常适合删除一小部分表。但是,一次(或更多)删除 20 个表是不切实际的。我将重新调整问题的重点以使其更清晰。
    • 对不起,这是您唯一的选择。你可以为此构造一个存储函数,但很有可能你会在脚下开枪:丢掉太多桌子......
    • 功能添加,玩得开心!请注意,这可能会破坏您的整个数据库。
    • 只是少了一个|| ' CASCADE ';,它是完美的
    【解决方案2】:

    这是这个问题的另一个 hackish 答案。它适用于ubuntu,也许也适用于其他一些操作系统。在 postgres 命令提示符中执行 \dt(在我的情况下,命令提示符在 genome-terminal 中运行)。然后你会在终端中看到很多表格。现在使用genome-terminalctrl+click-drag 功能复制所有表的名称。 Open python,做一些字符串处理(用''替换'',然后用','替换'\n'),你会得到所有表的逗号分隔列表。现在在 psql shell 中执行drop table CTRL+SHIFT+V 就完成了。我知道这太具体了,我只想分享。 :)

    【讨论】:

    • 这很好用,它可以让您轻松明确自己想要做什么。
    • 我的做法类似,我写:DROP TABLE whatever_然后按TAB,将所有表格复制到剪贴板,打开sublime,查找/替换,用正则表达式替换,\s+, 并粘贴到终端上。
    • 是的,这适用于 5 到多张桌子。对于长列表,请运行表名查询,使用 \e 从 psql 跳转到您的编辑器,复制您的列表并放置逗号。
    • 另外,在 pgadmin3 中,如果您选择架构名称,然后转到“依赖项”选项卡,您可以选择所有表(使用 shift 键),然后使用 CTRL + C 将它们全部复制。然后使用一些文本编辑器以形成 DROP TABLE [name,..] 查询。
    【解决方案3】:

    我用过这个。

    echo "select 'drop table '||tablename||';' from pg_tables where tablename like 'name%'" | \
        psql -U postgres -d dbname -t | \
        psql -U postgres -d dbname
    

    用适当的值替换dbnamename%

    【讨论】:

      【解决方案4】:

      我一直觉得创建一个我可以在运行之前查看和测试的 sql 脚本比依赖于让 plpgsql 恰到好处,这样它就不会破坏我的数据库更舒服。 bash 中的一些简单操作从目录中选择表名,然后为我创建 drop 语句。所以对于 8.4.x,你会得到这个基本查询:

      SELECT 'drop table '||n.nspname ||'.'|| c.relname||';' as "Name" 
      FROM pg_catalog.pg_class c
           LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
      WHERE c.relkind IN ('r','v','S','')
           AND n.nspname <> 'pg_catalog'
           AND n.nspname <> 'information_schema'
           AND n.nspname !~ '^pg_toast'
      AND pg_catalog.pg_table_is_visible(c.oid);
      

      您可以在其中添加 where 子句。 (where c.relname ilike 'bubba%')

      输出如下所示:

               Name          
      -----------------------
       drop table public.a1;
       drop table public.a2;
      

      因此,将其保存到 .sql 文件并使用 psql -f filename.sql 运行它

      【讨论】:

      • 作为后续,如果你把所有需要删除的表放到同一个schema中,你可以用cascade来删除它:drop schema abc cascade;
      • 请注意,此查询还将为它找到的任何序列 (relkind = 'S') 生成一个drop table 命令。序列上的drop table 将失败。相反,从relkind IN 子句中删除'S'。如果您需要删除序列,请使用常量数据select 'drop sequence' 构造一个类似的查询,这次使用c.relkind = 'S'
      【解决方案5】:

      披露:此答案适用于 Linux 用户。

      我会在@prongs 所说的内容中添加一些更具体的说明:

      • \dt 可以支持通配符:例如,您可以运行 \dt myPrefix* 以仅选择要删除的表;
      • CTRL-SHIFT-DRAG 之后选择然后CTRL-SHIFT-C 复制文本;
      • vim 中,转到INSERT MODE 并粘贴带有CTRL-SHIFT-V 的表格;
      • ESC,然后运行:%s/[ ]*\n/, /g将其转换为逗号分隔列表,然后您可以将它(不包括最后一个逗号)粘贴到DROP TABLE % CASCADE中。

      【讨论】:

      • 即使只是 ctrl-shift-drag 提示也很有帮助。
      【解决方案6】:

      使用linux命令行工具,可以这样实现:

      psql -d mydb -P tuples_only=1 -c '\dt' | cut -d '|' -f 2 | paste -sd "," | sed 's/ //g' | xargs -I{} echo psql -d mydb -c "drop table {};"
      

      注意:最后一个回显在那里,因为我找不到在 drop 命令周围加上引号的方法,所以您需要复制并粘贴输出并自己添加引号。

      如果有人能解决这个小问题,那就太棒了。

      【讨论】:

        【解决方案7】:

        所以我今天遇到了这个问题。我通过 pgadmin3 加载了我的服务器数据库并这样做了。表格按字母顺序排序,因此 shift 和 click 然后删除效果很好。

        【讨论】:

        • 您可以这样做,但您必须使用“属性”窗口
        【解决方案8】:

        我喜欢来自@Frank Heikensthe answer。感谢那。无论如何,我想改进一点;

        假设我们的分区表名称是partitioned_table,并且我们有一个数字后缀,我们每次都会增加它。喜欢partitioned_table_00partitioned_table_01 ... partitioned_table_99

        CREATE OR REPLACE drop_old_partitioned_tables(schema_name TEXT, partitioned_table_name TEXT, suffix TEXT)
            RETURNS TEXT
            LANGUAGE plpgsql
        AS
        $$
        DECLARE
            drop_query text;
        BEGIN
            SELECT 'DROP TABLE IF EXISTS ' || string_agg(format('%I.%I', table_schema, table_name), ', ')
            INTO drop_query
            FROM information_schema.tables
            WHERE table_type = 'BASE TABLE'
              AND table_schema = schema_name
              AND table_name <= CONCAT(partitioned_table_name, '_', suffix) -- It will also drop the table which equals the given suffix
              AND table_name ~ CONCAT(partitioned_table_name, '_\d{2}');
            IF drop_query IS NULL THEN
                RETURN 'There is no table to drop!';
            ELSE
                EXECUTE drop_query;
                RETURN CONCAT('Executed query: ', (drop_query));
            END IF;
        END;
        $$;
        

        对于执行,您可以运行以下代码;

        SELECT drop_old_partitioned_tables('public', 'partitioned_table', '10')
        

        顺便说一句,如果您想对表进行每年分区,则表后缀应为年份,例如 partitioned_table_2021。即使您的数据更大而无法每年进行分区,您也可以像partitioned_table_2021_01 那样每月进行一次。不要忘记根据需要调整代码。

        【讨论】:

          【解决方案9】:

          感谢 Jon 的另一个解决方案:

          tables=`psql -d DBNAME -P tuples_only=1 -c '\dt' |awk -F" " '/table_pattern/ {print $3","}'`
          psql -d DBNAME -c "DROP TABLE ${tables%?};";
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-07
            • 2016-02-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多