Drop All Tables Except One in MySql - mysql

I have 100 tables in my database, I want to keep one only.
I tried something like below query:
DROP ALL TABLES EXCEPT my_table
But that doesn't seem to exist. any idea?

You can build a DROP TABLE statement with multiple listed tables, and run the query using MySQL prepared statements -
SET #tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO #tables FROM information_schema.tables
WHERE table_schema = 'Database1' AND table_name <> 'my_table';
SET #tables = CONCAT('DROP TABLE ', #tables);
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

You can't drop multiple tables in MySQL.
The easiest in your case would be to export the table you want to keep (using a tool like mysqldump), then drop and recreate the database.

I wonder why no one suggested to go to the directory :
C:\Program Files (x86)\Parallels\Plesk\Databases\MySQL\data\user_db\...
and delete them easily there? this is what I did and it seems working

If you have lots of tables, watch out for truncation by the GROUP_CONCAT function. It has a setting for maximum length of the returned string: group_concat_max_len
See: GROUP_CONCAT reference manual entry
This answer guided me to the solution:
MYSQL: How to define or get LONG string variables

You can build all drop statements output them info file and use file after that
SELECT CONCAT( 'DROP TABLE ', table_name , ';' ) AS statement FROM information_schema.tables WHERE table_name not like 'table_to_keep' and table_schema like 'your_schema' into outfile 'path_to_file;
source path_to_file;

You can use mysqldump , try it !
mysqldump -u[USERNAME] -p[PASSWORD]--add-drop-table --no-data [DATABASE] |
grep ^DROP |
grep -v 'my_table' |
mysql -u[USERNAME] -p[PASSWORD] [DATABASE]

Related

RENAME table if target table does not exist

I work with a legacy system and there are multiple batches that are executed after one another. In each of these batches there should be a rename of a table, although this rename should only happen once.
So, there could be:
RENAME TABLE oldName TO newName
in batch1 and batch2. However, in batch2 it would be best if this statement could just be ignored. Of course, it would be more clean to just memorize if the statement has been executed but this clean solution is near to impossible in the current code base.
So, I would like a MySQL solution that basically says: If table newName does not exist, then execute the rename command. Otherwise, do nothing and also do not send an error message.
Is this possible? If yes, how?
This has been answered...
Mysql: RENAME TABLE IF EXISTS
With the following code... (all credit to original author)
SELECT Count(*)
INTO #exists
FROM information_schema.tables
WHERE table_schema = [DATABASE_NAME]
AND table_type = 'BASE TABLE'
AND table_name = 'oldName';
SET #query = If(#exists=0,'RENAME TABLE oldName TO newName','SELECT \'nothing to rename\' status');
PREPARE stmt FROM #query;
EXECUTE stmt;
When you don't want to replace [DATABASE NAME] manually you can use the following variable
SELECT DATABASE() INTO #db_name FROM DUAL;

Mysql - Drop table if exists not working

I try to use the following code to empty a database (delete all tables) :
SELECT concat('DROP TABLE IF EXISTS ','`',table_schema,'`','.','`',table_name,'`',';') FROM information_schema.tables WHERE table_schema = 'DB';
I am getting an output of the commands, but nothing happens to the database. If I take an individual command from the output, and run it in the console, it works.
What am I doing wrong?
As you know, SELECT only returns the result of a query. It doesn't know you actually intend to execute the result of that query. (In most cases, that would make no sense.) You can use prepared statements to do what you want (untested):
SET #s:='';
SELECT #s:=concat(#s, 'DROP TABLE IF EXISTS ','`',table_schema,'`','.','`',table_name,'`',';') FROM information_schema.tables WHERE table_schema = 'DB';
PREPARE stm FROM #s;
EXECUTE stm;
DEALLOCATE PREPARE stm;
Why you're using SELECT statement, Simply try this query:
DROP TABLE IF EXISTS table_name;

How to delete all MySQL tables beginning with a certain prefix?

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?
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.
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
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?
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;

MySQL bulk drop table where table like?

DROP TABLE (
SELECT table_name
FROM information_schema.`TABLES`
WHERE table_schema = 'myDatabase' AND table_name LIKE BINARY 'del%');
I know this doesn't work! What is the equivalent for something like this in SQL? I can whip out a simple Python script to do this but was just wondering if we can do something with SQL directly. I am using MySQL. Thank you!
You can use prepared statements -
SET #tables = NULL;
SELECT GROUP_CONCAT('`', table_schema, '`.`', table_name,'`') INTO #tables FROM information_schema.tables
WHERE table_schema = 'myDatabase' AND table_name LIKE BINARY 'del%';
SET #tables = CONCAT('DROP TABLE ', #tables);
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
It will generate and execute a statement like this -
DROP TABLE myDatabase.del1, myDatabase.del2, myDatabase.del3;
A minor improvement to #Devart's answer:
SET #tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.`', table_name, '`') INTO #tables FROM
(select * from
information_schema.tables
WHERE table_schema = 'myDatabase' AND table_name LIKE 'del%'
LIMIT 10) TT;
SET #tables = CONCAT('DROP TABLE ', #tables);
select #tables;
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
This script should be executed repeatedly until the console's output is NULL
The changes are:
backtick (`) wrapping the table name (if it contains non standard characters)
added a LIMIT to avoid the truncation issue I commented about
added a "print" (select #tables;) to have some kind of control when to stop executing the script
If you just need to quickly drop a bunch of tables (not in pure SQL, so not directly answering this question) a one line shell command can do it:
echo "show tables like 'fsm%'" | mysql | tail +2 | while read t; do echo "drop table \`$t\`;"; done | mysql
I found it useful to add an IFNULL to Devart's solutions to avoid generating an error if there are no tables matching the query.
SET #tables = IFNULL(CONCAT('DROP TABLE ', #tables),'SELECT NULL;');
In addition to #Devart's answer:
If you have many tables, you may need to set group_concat_max_len:
SET group_concat_max_len = 4096;
You can do this quickly and easily if you have phpMyAdmin available and the requirement is to drop tables with a specific prefix. Go to the database you want, and show the list of all the tables. Since tables are shown in alphabetic order, the tables with the prefix for deletion will all appear together. Go to the first one, and click the tick box on the left hand side. Then scroll down to the last table with the prefix, hold down shift, and click the tick box. That results in all the tables with the prefix being ticked. Go to the bottom of the list, and select the action drop for all selected tables. Go through with the deletion, checking that the SQL generated looks right!

MySQL: how to drop multiple tables using single query?

I want to drop multiple tables with ease without actually listing the table names in the drop query and the tables to be deleted have prefix say 'wp_'
I've used a query very similar to Angelin's. In case you have more than a few tables, one has to increase the max length of group_concat. Otherwise the query will barf on the truncated string that group_concat returns.
This is my 10 cents:
-- Increase memory to avoid truncating string, adjust according to your needs
SET group_concat_max_len = 1024 * 1024 * 10;
-- Generate drop command and assign to variable
SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(CONCAT(table_schema,'.',table_name)),';') INTO #dropcmd FROM information_schema.tables WHERE table_schema='databasename' AND table_name LIKE 'my_table%';
-- Drop tables
PREPARE str FROM #dropcmd; EXECUTE str; DEALLOCATE PREPARE str;
Just sharing one of the solutions:
mysql> SELECT CONCAT(
"DROP TABLE ",
GROUP_CONCAT(TABLE_NAME)
) AS stmt
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = "your_db_name" AND TABLE_NAME LIKE "ur
condition" into outfile '/tmp/a.txt';
mysql> source /tmp/a.txt;
Simple solution without risk of error:
mysqldump create a file that contains DROP command like
DROP TABLE IF EXISTS `wp_matable`;
a 'grep' with "DROP TABLE wp_" give us the commands to execute
so drop is made by theses trhee lines (you can edit drop.sql to check which tables would be dropped before)
mysqldump -u user -p database > dump.sql
grep "DROP TABLE `wp_" dump.sql > drop.sql
mysql -u user -p database < drop.sql
Be careful with "_", need to be written with "\" before in Mysql like:
SELECT CONCAT('DROP TABLE',GROUP_CONCAT(CONCAT(table_schema,'.',table_name)),';') INTO #dropcmd FROM information_schema.tables WHERE table_schema='databasename' AND table_name LIKE '**my\\_table**%';
A less complicated solution when a large number of tables are needed to be deleted -
SELECT GROUP_CONCAT(table_name SEPARATOR ", ")
-> AS tables
-> FROM information_schema.tables
-> WHERE table_schema = "my_database_name"
-> AND table_name LIKE "wp_%";
+-------------------------------------------------------------------------
| tables
+-------------------------------------------------------------------------
| wp_t1, wp_t2, wp_t3, wp_t4, wp_t5, wp_t6, wp_t7, wp_t7, wp_ ..........
+-------------------------------------------------------------------------
Copy the table names. Then use -
DROP TABLE
-> wp_t1, wp_t2, wp_t3, wp_t4, wp_t5, wp_t6, wp_t7, wp_t7, wp_ ..........;
For the great mysqldump solution it's better to use the option --skip-quote-names
mysqldump --skip-quote-names -u user -p database > dump.sql
grep "DROP TABLE wp_" dump.sql > drop.sql
mysql -u user -p database < drop.sql
You get rid of backticks in table names. The grep part won't work in some enviroments with the backticks.
Go to c:\xampp\mysql\data\your folder
Select multiple tables that you want remove and then press delete button
Thanks
Dropping single table in mysql:
DROP TABLE TABLE_NAME;