如何删除所有以某个前缀开头的 MySQL 表?
Posted
技术标签:
【中文标题】如何删除所有以某个前缀开头的 MySQL 表?【英文标题】:How to delete all MySQL tables beginning with a certain prefix? 【发布时间】:2014-07-25 13:26:15 【问题描述】:我在这个问题上找到了另一个帖子,但我无法使用它的解决方案,所以我想我会问得更清楚更详细。
我有一个代表 vBulletin 论坛的大型 mysql 数据库。几年来,这个论坛每次视图都报错,每次新建一个表,命名为aagregate_temp_1251634200
、aagregate_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 表?的主要内容,如果未能解决你的问题,请参考以下文章