如何使用通配符在PostgreSQL中删除多个表


82

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

然而

DROP TABLE tablename*

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

是否有一种优雅的方法(易于记忆),可以在一个命令中使用通配符删除多个表?

Answers:


115

使用逗号分隔的列表:

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);
        RAISE INFO 'Dropped table: %', quote_ident(row.table_schema) || '.' || quote_ident(row.table_name);
    END LOOP;
END;
$$;

SELECT footgun('public', 'tablename');

3
谢谢回答!用逗号分隔的列表非常适合删除一小部分表。但是,一次(或多次)删除20个表是不实际的。我将重点放在更清楚的问题上。
汤姆·费纳

2
抱歉,这是您唯一的选择。您可以为此构造一个存储的函数,但是很有可能会丢下自己的脚:丢下太多桌子……
Frank Heikens 2010年

4
功能添加,玩得开心!请注意,这可能会破坏您的整个数据库。
Frank Heikens 2010年

只是缺少一个|| ' CASCADE ';,它是完美的
MFARID

28

这是对该问题的另一个棘手的答案。它可以工作,ubuntu也许还有其他操作系统。做一个\dt在Postgres的命令提示符(命令提示符是内部运行genome-terminal在我的情况)。然后,您将在终端中看到很多表格。现在使用的ctrl+click-drag功能genome-terminal复制所有表的名称。在此处输入图片说明打开python,进行一些字符串处理(用','替换'',然后用','替换'\ n'),您将得到所有表的逗号分隔列表。现在在psql shell中执行a即可drop table CTRL+SHIFT+V完成。我知道我想分享的内容太具体了。:)


这很好用,它使您可以轻松地明确要执行的操作。
布拉德·科赫

5
我做的是相似的,我写:DROP TABLE whatever_然后按TAB键,所有表复制到剪贴板,开放的壮美,查找/替换,并替换使用正则表达式,\s+用于,粘贴在终端。
阿方索·佩雷斯(AlfonsoPérez)2014年

是的,这是5到许多表。对于长列表,请运行表名查询,使用\e,将psql踢出您的编辑器,在列表中复制并放置逗号。
Merlin

另外,在pgadmin3中,如果您选择模式名称,然后转到选项卡“ Dependants”,则可以选择所有表(使用Shift键),然后使用CTRL + C复制它们。然后使用一些文本编辑器形成DROP TABLE [名称,..]查询。
MateŠimović19年

18

我用这个

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

在替换为适当的值dbnamename%


12

我一直觉得创建一个我可以在运行它之前进行审阅和测试的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运行它


作为后续操作,如果将所有需要删除的表放入同一模式,则可以使用cascade将其删除。
Scott Marlowe's

请注意,此查询还将drop table针对找到的任何序列(relkind = 'S')生成命令。 drop table在序列上将失败。而是'S'relkind IN子句中删除。如果需要删除序列,请select 'drop sequence'使用c.relkind = 'S'
mrjmh

9

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

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

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

3

使用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命令周围加上引号的方法,因此您需要复制和粘贴输出并自己添加引号。

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


1

所以我今天遇到了这个问题。我通过pgadmin3加载了我的服务器数据库,并且这样做了。表是按字母顺序排序的,因此在单击后先进行删除和删除的效果很好。


你可以这样做,但你必须使用“属性”窗口
马特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.