17

I've found another thread on this question, but I wasn't able to use its solutions, so I thought I'd ask with more clarity and detail.

I have a large MySQL database representing a vBulletin forum. For several years, this forum has had an error generated on each view, each time creating a new table named aagregate_temp_1251634200, aagregate_temp_1251734400, etc etc. There are about 20,000 of these tables in the database, and I wish to delete them all.

I want to issue a command that says the equivalent of DROP TABLE WHERE TABLE_NAME LIKE 'aggregate_temp%';.

Unfortunately this command doesn't work, and the Google results for this problem are full of elaborate stored procedures beyond my understanding and all seemingly tailored to the more complex problems of different posters.

Is it possible to write a simple statement that drops multiple tables based on a name like match?

Jesse Nickles
  • 1,435
  • 1
  • 17
  • 25
GreenTriangle
  • 2,382
  • 2
  • 21
  • 35
  • As an admin with the `FILE` privilege, I'd do this from the command line: `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';`. – Wrikken Jun 04 '14 at 18:45
  • http://stackoverflow.com/questions/456751/drop-mysql-databases-matching-some-wildcard – usha Jun 04 '14 at 18:45

4 Answers4

16

There's no single statement to do that.

The simplest approach is to generate a set of statements, and execute them individually.

We can write a simple query that will generate the statements for us:

 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

The SELECT statement returns a rowset, but each row conveniently contains the exact SQL statement we need to execute to drop a table. (Note that information_schema is a builtin database that contains metadata. We'd need to replace mydatabase with the name of the database we want to drop tables from.

We can save the resultset from this query as a plain text file, remove any heading line, and voila, we've got a script we can execute in our SQL client.

There's no need for an elaborate stored procedure.

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

A little googling found this:

SELECT 'DROP TABLE "' + TABLE_NAME + '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE 'prefix%'

This should generate a script.

Source: Drop all tables whose names begin with a certain string

Mukus
  • 4,870
  • 2
  • 43
  • 56
Frederik Spang
  • 3,379
  • 1
  • 25
  • 43
  • This is one of the solutions that I tried, but couldn't get to work. I'm actually not even sure how to format it; if I execute it literally, it runs but nothing happens. I assume that I'm supposed to replace INFORMATION_SCHEMA.TABLES with the name of the database I'm actually working with, but MYSITE.TABLES yields `table 'mysite.tables' doesn't exist`, so I'm not sure what to do with it. – GreenTriangle Jun 04 '14 at 19:04
  • 1
    The '+' needs to be replaced with concat in mysql – crafter Sep 07 '20 at 21:45
  • 1
    Adding `AND TABLE_TYPE = 'BASE TABLE'` would avoid script errors when there are views in the database. – rymdsmurf Jan 21 '22 at 09:46
5

From memory you have to use prepared statements, for example: plenty of samples on stack exchange

I would recommend this example:

SQL: deleting tables with prefix

The SQL from above, this one includes the specific databasename - it builds it for you

SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' ) 
AS statement FROM information_schema.tables 
WHERE table_schema = 'database_name' AND table_name LIKE 'myprefix_%';

Here is a different way to do it:

MySQL bulk drop table where table like?

Community
  • 1
  • 1
n34_panda
  • 2,577
  • 5
  • 24
  • 40
3

This will delete all tables with prefix "mg_"

No need to copy and paste rowsets and in phpadmin copying and pasting is problematic as it will cut off long table names and replace them with '...' ruining set of sql commands.

Also note that '_' is a special character so thats why 'mg_' should be encoded as 'mg\_'

(and FOREIGN_KEY_CHECKS needs to be disabled in order to avoid error messages)

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; 
Alex Novikov
  • 138
  • 6