235

How do I drop all tables in Windows MySQL, using command prompt? The reason I want to do this is that our user has access to the database drops, but no access to re-creating the database itself, for this reason we must drop the tables manually. Is there a way to drop all the tables at once? Bear in mind that most of the tables are linked with foreign keys so they would have to be dropped in a specific order.

Machavity
  • 30,841
  • 27
  • 92
  • 100
Mantas
  • 3,179
  • 4
  • 20
  • 32
  • 3
    A similar question has been asked before http://stackoverflow.com/questions/3476765/mysql-drop-all-tables-ignoring-foreign-keys?lq=1 – tranceporter Sep 13 '12 at 10:00
  • See this answer: http://stackoverflow.com/questions/1912813/truncate-all-tables-in-a-mysql-database-in-one-command/8912749#8912749 – Ralph Jul 17 '13 at 16:07
  • 3
    It seems OP is asking to drop all tables from the command prompt, not from MySQL (as it's on the linked question), so in my opinion it's not duplicate. – kenorb Oct 27 '14 at 11:42
  • 1
    See also: [How to drop all MySQL tables from the command-line?](http://superuser.com/q/308071/87805). – kenorb Oct 27 '14 at 11:42
  • 2
    None of the linked question are the same as this one. This question is not duplicate! – Kostanos Nov 16 '14 at 17:00
  • 1
    Asked the question 2 years ago, and still think it's not a duplicate one, mainly because most of the other answers simply drop the database and re-create it. However it was specifically said that one does not want to drop the database itself – Mantas Nov 27 '14 at 14:48
  • @Mantas Just voted to reopen this as I don't think it is a duplicate either and the accepted answer is far better than the one in the duplicate. If anything, the duplicates should be inverted. – Zze Mar 22 '18 at 10:25

5 Answers5

330

You can generate statement like this: DROP TABLE t1, t2, t3, ... and then use prepared statements to execute it:

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; 
Fabian Schmengler
  • 24,155
  • 9
  • 79
  • 111
Devart
  • 119,203
  • 23
  • 166
  • 186
  • 6
    Well this needs a bit of tweaking as it cannot drop the tables that are constrained by keys – Mantas Sep 13 '12 at 10:17
  • 13
    This works fine if we SET FOREIGN_KEY_CHECKS = 0; and do SET FOREIGN_KEY_CHECKS = 1; after deletion this will allow us to delete all tables without having key checks; – Mantas Sep 13 '12 at 10:24
  • That is because DROP TABLE drops tables one by one, and doesn't bother of dependent objects (related tables). So FOREIGN_KEY_CHECKS should help. – Devart Sep 13 '12 at 11:27
  • 11
    NB It may also be necessary to increase `GROUP_CONCAT_MAX_LEN` and to escape the schema and name with ``GROUP_CONCAT('`', table_schema, '`.`', table_name, '`')``. – Peter Taylor Aug 26 '13 at 16:46
  • 1
    I'm running this, and got strange errors: `ERROR 1051 (42S02) at line 9: Unknown table 'catalog_catego'`. There is no such table in my DB, but the real name of table is `catalog_category` - it looks like the last two chars were eat. It happens only for some tables. Any idea? – Kostanos Aug 30 '13 at 16:43
  • 1
    I found, the problem was `GROUP_CONCAT_MAX_LEN` I have a lot of tables. I edited your answer to have these variables set. Thank you to @PeterTaylor too! – Kostanos Aug 30 '13 at 16:50
  • I added the small improvement to the query, in case when there is no tables on the database. If no, the current script will rise the mysql error with NULL value. – Kostanos Sep 04 '13 at 23:37
  • 4
    CONCAT "DROP TABLE " must includes " IF EXIST ", this has been reduced my time. – Govind Totla Jan 09 '14 at 07:56
  • 13
    This is not the best solution. @Kostonos fixed an important issue with this command and edited Devart's answer, but it was not accepted. Please see Kostanos' answer on this page. (http://stackoverflow.com/a/18625545/114558) – rinogo Mar 14 '14 at 05:29
  • 1
    @rinogo The answer should give an idea for people. Then you can change/edit any solution to make it the best for you. – Devart Mar 14 '14 at 07:27
  • I get 500 status code (rejected) – Black Feb 14 '19 at 09:15
  • MySQL is a usability nightmare :/ – Sliq Aug 20 '21 at 09:26
294

The @Devart's version is correct, but here are some improvements to avoid having error. I've edited the @Devart's answer, but it was not accepted.

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;

This script will not raise error with NULL result in case when you already deleted all tables in the database by adding at least one nonexistent - "dummy" table.

And it fixed in case when you have many tables.

And This small change to drop all view exist in the Database

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;

It assumes that you run the script from Database you want to delete. Or run this before:

USE REPLACE_WITH_DATABASE_NAME_YOU_WANT_TO_DELETE;

Thank you to Steve Horvath to discover the issue with backticks.

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
Kostanos
  • 9,615
  • 4
  • 51
  • 65
  • Actually, it does raise an error. – arthurprs Oct 03 '13 at 14:22
  • Could you be more specific please? Which error did you get? – Kostanos Oct 03 '13 at 15:11
  • My mistake, it's actually a warning because 'dummy' tables doesn't exists. – arthurprs Oct 03 '13 at 15:24
  • I don't get this warning. If you see on the query it does `DROP TABLE IF EXISTS` – Kostanos Oct 03 '13 at 15:36
  • Yes, precisely. For some reason my 5.6 install gives a warning on those if the table doesn't exists. – arthurprs Oct 03 '13 at 15:49
  • Any way it is better then an exception which I got when the database was already cleaned, the @tables is NULL on that case, this when we need add dummy table, to have something on that list. – Kostanos Oct 04 '13 at 08:16
  • 3
    for the overly cautious, `SELECT @tables\G` after the last SELECT above will give you a listing of what's about to be dropped - look over it before executing the second half of the snippet – rymo Feb 20 '14 at 16:34
  • A tiny issue with both solutions is that the backticks are missing from around the table names, which can throw things out. The other solution is easier to edit for this effect, though. – Steve Horvath Aug 29 '14 at 07:07
  • @SteveHorvath could you please give me an example of a table name, that could break this store procedure? I would like to test it and to improve the function. Thanks. – Kostanos Sep 01 '14 at 18:13
  • @Kostanos sure: "group" for example, but any reserved word will do. – Steve Horvath Sep 04 '14 at 01:26
  • 1
    @SteveHorvath thank you to pointing the issue with backticks. I fixed the query and it runs perfectly now with (group, select and other tables). – Kostanos Sep 04 '14 at 13:05
  • 2
    This is the proper answer – Attila Fulop Sep 28 '14 at 20:58
  • Still not working: `#1044 - Access denied for user 'root'@'%' to database 'information_schema'`, Any idea? – tokyodrift Jun 19 '20 at 10:59
  • I can't manage to change foreign_key_checks = OFF when I run it on Mariadb. It throws an error. In Heidisql gui it shows off as a background color, but if I set it ON it shows it bright blue. I think it's a permissions. i can set them outsdie procedure. And I didn't find much documentation on this either – gcr Apr 10 '21 at 20:14
  • I don't get the *error problem*, which is supposed to be solved by `SELECT IFNULL(@tables,'dummy') INTO @tables;`: *This script will not raise error with NULL result in case when you already deleted all tables in the database by adding at least one nonexistent - "dummy" table.* So the script in the accepted answer does always raise an error - but why exactly? – BairDev May 18 '22 at 07:22
92

Try this.

This works even for tables with constraints (foreign key relationships). Alternatively you can just drop the database and recreate, but you may not have the necessary permissions to do that.

mysqldump -u[USERNAME] -p[PASSWORD] \
  --add-drop-table --no-data [DATABASE] | \
  grep -e '^DROP \| FOREIGN_KEY_CHECKS' | \
  mysql -u[USERNAME] -p[PASSWORD] [DATABASE]

In order to overcome foreign key check effects, add show table at the end of the generated script and run many times until the show table command results in an empty set.

TRiG
  • 10,148
  • 7
  • 57
  • 107
MutantMahesh
  • 1,480
  • 15
  • 20
  • 1
    Wish I could vote this up twice. So simple and plays really nicely with environments like AWS Beanstalk where everything comes in from env vars anyway. Just `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 Jan 22 '16 at 05:56
  • A very neat solution – andynormancx Mar 27 '16 at 14:23
  • 1
    Love the idea. Here's the same thing for all database a user have access to: `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 Apr 12 '16 at 13:30
50

You can drop the database and then recreate it with the below:-

mysql> drop database [database name];
mysql> create database [database name];
Prahalad Gaggar
  • 11,389
  • 16
  • 53
  • 71
user1086159
  • 1,045
  • 5
  • 16
  • 24
6

The accepted answer does not work for databases that have large numbers of tables, e.g. Drupal databases. Instead, see the script here: https://stackoverflow.com/a/12917793/1507877 which does work on MySQL 5.5. CAUTION: Around line 11, there is a "WHERE table_schema = SCHEMA();" This should instead be "WHERE table_schema = 'INSERT NAME OF DB INTO WHICH IMPORT WILL OCCUR';"

Community
  • 1
  • 1
Giles B
  • 411
  • 4
  • 7
  • 3
    By the way, if doing Drupal development, the really easy way to do this is with the drush command line tool. The command is: drush sql-drop – Giles B Aug 24 '16 at 14:00