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

时间:2010-11-17 06:49:43

标签: sql postgresql

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

然而

DROP TABLE tablename*

不起作用。 (不遵守通配符)。

使用通配符在一个命令中删除多个表是否有优雅(读取:易记)的方式?

9 个答案:

答案 0 :(得分:100)

使用逗号分隔列表:

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');

答案 1 :(得分:25)

这是另一个解决这个问题的黑客问题。它适用于ubuntu,也许还有其他一些操作系统。在postgres命令提示符下执行\dt(在我的情况下,命令提示符在genome-terminal内运行)。然后你会在终端看到很多桌子。现在使用ctrl+click-drag的{​​{1}}功能复制所有表格'名。 enter image description here打开python,进行一些字符串处理(替换''''然后' \ n' by',&# 39;)然后你得到所有表的逗号分隔列表。现在在psql shell中执行genome-terminal并完成。我知道它太具体了,我只想分享。 :)

答案 2 :(得分:12)

我用过这个。

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

答案 3 :(得分:8)

我一直觉得创建一个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子句。 (其中c.relname ilike'bubba%')

输出如下:

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

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

运行它

答案 4 :(得分:7)

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

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

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

答案 5 :(得分:2)

使用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命令周围放置引号的方法,所以你需要复制并粘贴输出并自己添加引号。

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

答案 6 :(得分:1)

所以今天我遇到了这个问题。我通过pgadmin3加载了我的服务器数据库并按照这种方式执行。表格按字母顺序排序,因此移位和点击后删除效果很好。

答案 7 :(得分:1)

我喜欢 the answer 中的 @Frank Heikens。感谢那。不管怎样,我想改进一下;

让我们假设我们的分区表名称是 {{ "config_changes": [ { "new_val": { "db": "dbName", "durability": "hard", "id": "0f72a570-7998-49f7-affc-96cbdd1ea086", "indexes": [], "name": "tableName", "primary_key": "id", "shards": [ { "nonvoting_replicas": [], "primary_replica": "replicasssss_iu1", "replicas": [ "replicasssss_iu1" ] } ], "write_acks": "majority" }, "old_val": null } ], "tables_created": 1 }} 并且我们有一个数字后缀,我们每次都会增加它。像partitioned_tablepartitioned_table_00 ... partitioned_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 一样按月进行分区。不要忘记根据您的需要调整您的代码。

答案 8 :(得分:0)

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

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