如何在没有DROP数据库权限的情况下,通过命令行删除所有MySQL表?

236

如何在Windows MySQL中使用命令提示符删除所有表?我想这样做的原因是我们的用户可以删除数据库,但无法重新创建数据库本身,因此我们必须手动删除表。有没有一种方式可以一次删除所有表?请注意,大多数表都与外键相关联,因此必须按特定顺序删除它们。


3
之前有类似的问题被提出过:https://dev59.com/lHA75IYBdhLWcg3wGU-I?lq=1。 - tranceporter
3
似乎OP希望从命令提示符中删除所有表,而不是从MySQL中删除(因为它在链接的问题中),所以我认为这不是重复的。 - kenorb
1
另请参阅:如何从命令行删除所有MySQL表? - kenorb
2
这些链接的问题都不同于此问题。这个问题不是重复的! - Kostanos
1
两年前问过这个问题,仍然认为它不是一个重复的问题,主要是因为大多数其他答案只是删除数据库并重新创建它。然而,明确表示不想删除数据库本身。 - Mantas
显示剩余2条评论
5个回答

331

您可以生成这样的语句:DROP TABLE t1,t2,t3,...,然后使用准备好的语句来执行:

SET FOREIGN_KEY_CHECKS = 0; 
SET @tables = NULL;
SELECT GROUP_CONCAT('`', table_schema, '`.`', table_name, '`') INTO @tables
  FROM information_schema.tables 
  WHERE table_schema = 'database_name'; -- specify DB name here.

SET @tables = CONCAT('DROP TABLE ', @tables);
PREPARE stmt FROM @tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1; 

6
这需要进行一些微调,因为它无法删除受键约束限制的表。 - Mantas
13
如果我们执行 SET FOREIGN_KEY_CHECKS = 0;,并在删除后执行 SET FOREIGN_KEY_CHECKS = 1;,则可以正常工作。这将允许我们在没有键检查的情况下删除所有表格。 - Mantas
11
可能需要增加 GROUP_CONCAT_MAX_LEN 的值,并使用 GROUP_CONCAT('`', table_schema, '`.`', table_name, '`') 对模式和名称进行转义。 - Peter Taylor
4
CONCAT函数中必须包含"IF EXISTS",这能够减少我的时间。 - Govind Totla
13
这不是最佳解决方案。@Kostonos使用这个命令修复了一个重要的问题并编辑了Devart的答案,但没有被接受。请参见此页面上Kostanos的答案。(https://dev59.com/dWct5IYBdhLWcg3wCJF-#18625545) - rinogo
显示剩余7条评论

294

@Devart的版本是正确的,但是这里有一些改进可以避免出错。我编辑了@Devart的答案,但是它没有被接受。

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

如果您在数据库中添加至少一个不存在的“虚拟”表,此脚本将不会在NULL结果时引发错误(例如,您已经删除了所有表)。

如果您有许多表,则修复了此问题。

并且此小更改可用于删除数据库中存在的所有视图。

SET FOREIGN_KEY_CHECKS = 0;
SET GROUP_CONCAT_MAX_LEN=32768;
SET @views = NULL;
SELECT GROUP_CONCAT('`', TABLE_NAME, '`') INTO @views
  FROM information_schema.views
  WHERE table_schema = (SELECT DATABASE());
SELECT IFNULL(@views,'dummy') INTO @views;

SET @views = CONCAT('DROP VIEW IF EXISTS ', @views);
PREPARE stmt FROM @views;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;

它假设您从要删除的数据库中运行脚本。或在此之前运行此命令:

USE REPLACE_WITH_DATABASE_NAME_YOU_WANT_TO_DELETE;

感谢 Steve Horvath 发现反引号的问题。


实际上,它确实会引发一个错误。 - arthurprs
是的,确切地说。由于某种原因,如果表不存在,我的5.6安装会对它们发出警告。 - arthurprs
3
对于过度谨慎的人,执行上面最后一个SELECT语句后加上\G会列出即将被删除的内容 - 在执行代码片段的下半部分之前请先查看它。 - rymo
1
@SteveHorvath 感谢您指出使用反引号的问题。我已经修复了查询语句,现在可以完美地运行(包括分组、选择和其他表)。 - Kostanos
2
这是正确的答案。 - Attila Fulop
显示剩余10条评论

92

试一试。

这甚至适用于具有约束条件(外键关系)的表。或者,您可以只删除数据库并重新创建,但您可能没有执行该操作所需的权限。

mysqldump -u[USERNAME] -p[PASSWORD] \
  --add-drop-table --no-data [DATABASE] | \
  grep -e '^DROP \| FOREIGN_KEY_CHECKS' | \
  mysql -u[USERNAME] -p[PASSWORD] [DATABASE]
为了克服外键检查的影响,在生成的脚本末尾添加show table,并多次运行,直到show table命令结果为空集。

1
希望我可以点赞两次。非常简单,并且与 AWS Beanstalk 等环境完美协作,因为所有东西都从环境变量中获取。只需键入 mysqldump -h $RDS_HOSTNAME -u $RDS_USERNAME -p $RDS_PASSWORD --add-drop-table --no-data $RDS_DB_NAME | grep -e '^DROP \| FOREIGN_KEY_CHECKS' | mysql -h $RDS_HOSTNAME -u $RDS_USERNAME -p $RDS_PASSWORD $RDS_DB_NAME - Mat Schaffer
一个非常整洁的解决方案 - andynormancx
1
喜欢这个想法。以下是用户可以访问的所有数据库的相同内容: mysqldump --host=127.0.0.1 --all-databases --user=$mysql_user --password=$mysql_password --add-drop-table --no-data | grep -e '^DROP \| FOREIGN_KEY_CHECKS\|USE' | mysql --host=127.0.0.1 --user=$mysql_user --password=$mysql_password - Vincent Fenet

50

您可以使用以下方法删除 数据库,然后重新创建它:

mysql> drop database [database name];
mysql> create database [database name];

27
正如我所说,用户没有创建数据库的权限,我们只能创建、更新和删除表格。 - Mantas
28
如果你的数据库有一些特定配置,例如编码、权限等,那么这个解决方案也是不正确的。 - Kostanos
7
使用时存在危险。你还可能会丢失你忘记检查的数据库设置... - obayhan
最简单的替代方案。 - Rajat Saxena
2
在运行此命令之前,可以使用“show create database database_name”命令。 - chandramohan
当人们陷入这个问题时,显然这不是他们寻找的东西。 - ram4nd

6
接受的答案对于具有大量表格的数据库(例如Drupal数据库)不起作用。相反,请参见此处的脚本: https://dev59.com/lHA75IYBdhLWcg3wGU-I#12917793,它可以在MySQL 5.5上运行。注意:在第11行左右,有一个“WHERE table_schema = SCHEMA();”,这应该改为“WHERE table_schema ='插入要导入的数据库名称';”。

3
顺便说一下,如果进行Drupal开发,最简单的方法是使用drush命令行工具。命令是:drush sql-drop。 - Giles B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接