【问题标题】:How to delete all MySQL tables beginning with a certain prefix?如何删除所有以某个前缀开头的 MySQL 表?
【发布时间】:2014-07-25 13:26:15
【问题描述】:

我在这个问题上找到了另一个帖子,但我无法使用它的解决方案,所以我想我会问得更清楚更详细。

我有一个代表 vBulletin 论坛的大型 MySQL 数据库。几年来,这个论坛每次视图都报错,每次新建一个表,命名为aagregate_temp_1251634200aagregate_temp_1251734400等。数据库中大约有20000个这样的表,我想删除它们全部。

我想发出一个相当于DROP TABLE WHERE TABLE_NAME LIKE 'aggregate_temp%'; 的命令。

不幸的是,这个命令不起作用,并且这个问题的谷歌结果充满了我无法理解的复杂存储过程,并且似乎都是针对不同海报的更复杂问题量身定制的。

是否可以编写一个基于name like 匹配删除多个表的简单语句?

【问题讨论】:

  • 作为具有FILE 权限的管理员,我会从命令行执行此操作:SELECT CONCAT('DROP TABLE ', TABLE_SCHEMA,'.',TABLE_NAME,';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'aggregate_temp%' INTO OUTFILE '/tmp/drops.sql'; SOURCE /tmp/drops.sql';

标签: mysql sql


【解决方案1】:

没有单一的语句可以做到这一点。

最简单的方法是生成一组语句,然后分别执行。

一个简单的查询可以为您生成语句:

 SELECT CONCAT('DROP TABLE `',t.table_schema,'`.`',t.table_name,'`;') AS stmt
   FROM information_schema.tables t
  WHERE t.table_schema = 'mydatabase'
    AND t.table_name LIKE 'aggregate\_temp%' ESCAPE '\\'
  ORDER BY t.table_name

这只是返回一个行集,但这些行方便地包含您需要执行的确切 SQL 语句。 (请注意,information_schema 是一个包含元数据的内置数据库。您只需将 mydatabase 替换为要从中删除表的数据库的名称。

将此查询的结果集保存为纯文本文件,删除任何标题行,瞧,您已经有了一个可以在 SQL 客户端中执行的脚本。

不需要复杂的存储过程。

【讨论】:

    【解决方案2】:

    用谷歌搜索一下发现了这个:

    SELECT 'DROP TABLE "' + TABLE_NAME + '"' 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_NAME LIKE 'prefix%'
    

    这应该会生成一个脚本。

    来源Drop all tables whose names begin with a certain string

    【讨论】:

    • 这是我尝试过的解决方案之一,但无法正常工作。我实际上什至不确定如何格式化它。如果我从字面上执行它,它会运行但没有任何反应。我假设我应该将 INFORMATION_SCHEMA.TABLES 替换为我实际使用的数据库的名称,但 MYSITE.TABLES 产生table 'mysite.tables' doesn't exist,所以我不确定如何处理它。
    • mysql中的'+'需要用concat替换
    • 添加AND TABLE_TYPE = 'BASE TABLE'可以避免数据库中有视图时出现脚本错误。
    【解决方案3】:

    从内存中你必须使用准备好的语句,例如:堆栈交换上的大量样本

    我会推荐这个例子:

    SQL: deleting tables with prefix

    上面的 SQL,其中包含特定的数据库名称 - 它为您构建它

    SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' ) 
    AS statement FROM information_schema.tables 
    WHERE table_schema = 'database_name' AND table_name LIKE 'myprefix_%';
    

    这是一种不同的方法:

    MySQL bulk drop table where table like?

    【讨论】:

    • 运行 SET GROUP_CONCAT_MAX_LEN=10000;之前
    【解决方案4】:

    这将删除所有带有前缀“mg_”的表

    不需要复制和粘贴行集,在 phpadmin 中复制和粘贴是有问题的,因为它会切断长表名并用 '...' 替换它们,破坏 sql 命令集。

    还要注意'_'是一个特殊字符,所以'mg_'应该被编码为'mg\_'

    (并且需要禁用 FOREIGN_KEY_CHECKS 以避免出现错误消息)

    SET FOREIGN_KEY_CHECKS = 0;
    SET GROUP_CONCAT_MAX_LEN=32768;
    SET @tables = NULL;
    SELECT GROUP_CONCAT('`', table_name, '`') INTO @tables
      FROM information_schema.tables
      WHERE table_schema = (SELECT DATABASE()) and table_name like 'mg\_%';
    SELECT IFNULL(@tables,'dummy') INTO @tables;
    
    SET @tables = CONCAT('DROP TABLE IF EXISTS ', @tables);
    PREPARE stmt FROM @tables;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    SET FOREIGN_KEY_CHECKS = 1; 
    

    【讨论】:

      猜你喜欢
      • 2019-08-13
      • 2010-09-05
      • 2010-09-08
      • 2011-03-27
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 2010-12-16
      • 2011-01-21
      相关资源
      最近更新 更多