I need to drop about 20k tables. I know the names of the tables that are NOT to be dropped.
If I have table names "a,b,c,d,e,f,g...", how can I drop all tables that are not in the list "a,b,c"?
I need to drop about 20k tables. I know the names of the tables that are NOT to be dropped.
If I have table names "a,b,c,d,e,f,g...", how can I drop all tables that are not in the list "a,b,c"?
You need to run select from information_schema.tables and create a cursor that will iterate through the results and perform the appropriate drops (use if statement). This is because drop statement does not support selecting/filtering or other options. (unless something has changed during the last two or three years)
When you're performing the select statement you can use something like:
WHERE table_name NOT IN ('ssss','dddd');
Another thing is: why do you have 20k tables in your database?????
I would suggest that you take the following approach
SHOW TABLES
(or from information_schema.TABLES
)DROP TABLE
commandNow you have an SQL script that you can run against the database
If you're a linux shell ninja might want to use commandline tools like uniq
, xargs
, etc to manipulate the files. Using a spreadsheet might be another way to deal with it.
Try this to get a resultset of SQL DROP statements:
SELECT CONCAT('DROP TABLE ', TABLE_NAME , ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='YourDatabase'
AND TABLE_NAME NOT IN ('Table1', 'Table2');
Copy and paste the results, and you've got 20,000-n DROP statements.
I ran into this exact same problem today. Here is one approach for skipping tables ABC, DEF and XYZ:
mysql -Nu USER --password=PASSWORD DATABASE -e 'show tables' | \
perl -ne 'BEGIN { print "SET FOREIGN_KEY_CHECKS=0;\n" };
!/^(ABC|DEF|XYZ)$/ && s/^(.*)/DROP TABLE `\1`;/ && print' | \
mysql -u USER --password=PASSWORD DATABASE
So what the devil is all that?
There is a much easier way. In one line, on your command line type:
mysql -u root -p[password] --skip-column-names [database] -e "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='[database]' AND TABLE_NAME NOT IN ('[table 1]', '[table 2]',..'[table n]');" | cut -f1 | sed -r 's/(.*)/DROP TABLE IF EXISTS \1;/' | mysql -u root -p[password] [database]
You may get two warnings about including passwords in a command. If this may be a problem, you can clear the command history to 'remove the evidence' :-)
history -c
I'm going to suggest a completely different approach if you can get away with the tables that you want to keep being made unavailable for a short period of time.
DROP DATABASE
the database with all of the tables in