如何删除所有以某个前缀开头的 MySQL 表?

Posted

技术标签:

【中文标题】如何删除所有以某个前缀开头的 MySQL 表?【英文标题】:How to delete all MySQL tables beginning with a certain prefix? 【发布时间】: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'; ***.com/questions/456751/… 【参考方案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; 

【讨论】:

以上是关于如何删除所有以某个前缀开头的 MySQL 表?的主要内容,如果未能解决你的问题,请参考以下文章

删除所有以某个字符串开头的类

如何检查 CComBSTR 是不是以某个前缀开头?

删除名称以某个字符串开头的所有表

FilterListView - 从列表中删除不以提供的前缀开头的项目

mysql查询一个数据库中有特定前缀的表有多少个

如何从给定数据库中删除所有带有前缀“bkp”的表?