18

I need to drop hundreds of mysql databases that all share a common prefix, but have random id's as the rest of their name ( eg. database_0123456789, database_9876543210 ). All these databases are on the same server. There are other databases on that same server that I don't want to drop.

This is what I'd like to do:

DROP DATABASE `database_*`;

How can I drop these efficiently? Is there a MySQL query I can run? Maybe a shell script?

T. Brian Jones
  • 13,002
  • 25
  • 78
  • 117
  • 1
    SHOW DATABASES LIKE 'database_%' might be a decent start I'm pretty sure you can go Drop Database SHOW DATABASES LIKE "database_%" – VoronoiPotato Aug 16 '13 at 18:05
  • `SHOW DATABASES LIKE "database_%"` works, but it does not work when combined with `DROP DATABASE`. `DROP DATABASE LIKE "database_%"` does not work either. – T. Brian Jones Aug 16 '13 at 18:15
  • this link maybe could help:http://dba.stackexchange.com/questions/1018/mysql-drop-table-starting-with-a-prefix – Arash Mousavi Aug 16 '13 at 18:18
  • i hope you learn from this and use normalization next time. what you did is define a meta data column as a database name this is a SQL anti pattern – Raymond Nijland Aug 16 '13 at 18:21
  • 2
    @Raymond N: that's a possibility. But it's also possible that these databases were created by/for testing (JUnit tests) that didn't get cleaned up, or schemas used for testing deployments of changes for schema upgrades and rollbacks. There are some other possibilities which could explain why there are a lot of (now unneeded) databases. – spencer7593 Aug 16 '13 at 18:36
  • 2
    @spencer7593 true never crossed my mind thanks for your comment. – Raymond Nijland Aug 16 '13 at 18:43
  • 1
    possible duplicate of [SQL: deleting tables with prefix](http://stackoverflow.com/questions/1589278/sql-deleting-tables-with-prefix) – goozez Sep 30 '14 at 11:25

4 Answers4

39

The syntax of the DROP DATABASE statement supports only a single database name. You will need to execute a separate DROP DATABASE statement for each database.

You can run a query to return a list of database names, or maybe more helpful, to generate the actual statements you need to run. If you want to drop all databases that start with the literal string database_ (including the underscore character), then:

SELECT CONCAT('DROP DATABASE `',schema_name,'` ;') AS `-- stmt`
  FROM information_schema.schemata
 WHERE schema_name LIKE 'database\_%' ESCAPE '\\'
 ORDER BY schema_name

Copy the results from that query, and you've got yourself a SQL script.


(Save the results as plain text file (e.g. dropdbs.sql), review with your favorite text editor to remove any goofy header and footer lines, make sure the script looks right, save it, and then from the mysql command line tool, mysql> source dropdbs.sql.)

Obviously, you could get more sophisticated than that, but for a one-time shot, this is probably the most efficient.)

spencer7593
  • 106,611
  • 15
  • 112
  • 140
5

Don't need of an external script file. A stored procedure using prepare statements might do the trick:

CREATE PROCEDURE kill_em_all()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE dbname VARCHAR(255);
    DECLARE cur CURSOR FOR SELECT schema_name
      FROM information_schema.schemata
     WHERE schema_name LIKE 'database\_%' ESCAPE '\\'
     ORDER BY schema_name;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;

    read_loop: LOOP
        FETCH cur INTO dbname;

        IF done THEN
          LEAVE read_loop;
        END IF;

        SET @query = CONCAT('DROP DATABASE ',dbname);
        PREPARE stmt FROM @query;
        EXECUTE stmt;
    END LOOP;
END;

Once you have that procedure, you just have to:

CALL kill_em_all();

When done:

DROP PROCEDURE kill_em_all
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125
  • 3
    Yep. But personally I think I'd have trouble falling asleep at night, and have a nervous twitch during the day, with a procedure like this lurking on one of my MySQL instances. But a `DROP PROCEDURE kill_em_all` would cure that. – spencer7593 Aug 16 '13 at 19:37
2

This question lacks an answer without creating a file first.

Our build server automatically creates a database for every topic branch while running unit tests. After information_schema queries get really slow which causes our tests to fail.

I created a batch file which runs every day. I did not want to deal with temporary files. So here is my solution.

@ECHO OFF
REM drops all databases excluding defaults
SET user=user
SET pass=pass

mysql ^
-u %user% ^
-p%pass% ^
-NBe "SELECT CONCAT('drop database `', schema_name, '`;') from information_schema.schemata where schema_name NOT IN ('mysql', 'test', 'performance_schema', 'information_schema')" | mysql -u %user% -p%pass%
Jürgen Steinblock
  • 30,746
  • 24
  • 119
  • 189
0

Modifying spencer7593 answer

Here is the command to find desired results and save it in file where prefix is database prefix

 SELECT CONCAT('DROP DATABASE ',schema_name,' ;') AS stmt
 FROM information_schema.schemata
 WHERE schema_name LIKE 'prefix\_%' ESCAPE '\\'
 ORDER BY schema_name into outfile '/var/www/pardeep/file.txt';

if you get permission denied then change folder permission to 777 or change folder group to mysql using this

chown -R mysql /var/www/pardeep/

then run this query

source /var/www/pardeep/file.txt;
warvariuc
  • 57,116
  • 41
  • 173
  • 227
Pardeep Kumar
  • 1,629
  • 1
  • 11
  • 9
  • Hi warvariuc, I got notification about code and but I didn't find anything which you have changed except formatting. what I am missing here??? – Pardeep Kumar Mar 18 '16 at 12:11