SQL: deleting tables with prefix - mysql

How to delete my tables who all have the prefix myprefix_?
Note: need to execute it in phpMyAdmin

You cannot do it with just a single MySQL command, however you can use MySQL to construct the statement for you:
In the MySQL shell or through PHPMyAdmin, use the following query
SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' )
AS statement FROM information_schema.tables
WHERE table_name LIKE 'myprefix_%';
This will generate a DROP statement which you can than copy and execute to drop the tables.
EDIT: A disclaimer here - the statement generated above will drop all tables in all databases with that prefix. If you want to limit it to a specific database, modify the query to look like this and replace database_name with your own database_name:
SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' )
AS statement FROM information_schema.tables
WHERE table_schema = 'database_name' AND table_name LIKE 'myprefix_%';

Some of the earlier answers were very good.
I have pulled together their ideas with some
notions from other answers on the web.
I needed to delete all tables starting with 'temp_'
After a few iterations I came up with this block of code:
-- Set up variable to delete ALL tables starting with 'temp_'
SET GROUP_CONCAT_MAX_LEN=10000;
SET #tbls = (SELECT GROUP_CONCAT(TABLE_NAME)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'my_database'
AND TABLE_NAME LIKE 'temp_%');
SET #delStmt = CONCAT('DROP TABLE ', #tbls);
-- SELECT #delStmt;
PREPARE stmt FROM #delStmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
I hope this is useful to other MySQL/PHP programmers.

show tables like 'prefix_%';
copy the results and paste them into a text editor or output the query to a file, use a few search and replaces to remove unwanted formatting and replace \n with a comma
put a ; on the end and add drop table to the front.
you'll get something that looks like this:
drop table myprefix_1, myprefix_2, myprefix_3;

#andre-miller solution is good but there is even better and slightly more professional that will help you execute all in one go. Still will need more than one command but this solution will allow you to use the SQL for automated builds.
SET #tbls = (SELECT GROUP_CONCAT(TABLE_NAME)
FROM information_schema.TABLES
WHERE TABLE_NAME LIKE 'myprefix_%');
PREPARE stmt FROM 'DROP TABLE #tbls';
EXECUTE stmt USING #tbls;
DEALLOCATE PREPARE stmt;
Note: this code is platform dependant, it's for MySQL but for sure it could be implemented for Postgre, Oracle and MS SQL with slight changes.

SELECT CONCAT("DROP TABLE ", table_name, ";")
FROM information_schema.tables
WHERE table_schema = "DATABASE_NAME"
AND table_name LIKE "PREFIX_TABLE_NAME%";

I drop table successfully by edit query to like this
SET GROUP_CONCAT_MAX_LEN=10000;
SET FOREIGN_KEY_CHECKS = 0;
SET #tbls = (SELECT GROUP_CONCAT(CONCAT('`', TABLE_NAME, '`'))
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'pandora'
AND TABLE_NAME LIKE 'temp_%');
SET #delStmt = CONCAT('DROP TABLE ', #tbls);
-- SELECT #delStmt;
PREPARE stmt FROM #delStmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;

Just another solution using GROUP_CONCAT so it will execute one drop query like
DROP TABLE table1,table2,..
SET #Drop_Stm = CONCAT('DROP TABLE ', (
SELECT GROUP_CONCAT(TABLE_NAME) AS All_Tables FROM information_schema.tables
WHERE TABLE_NAME LIKE 'prefix_%' AND TABLE_SCHEMA = 'database_name'
));
PREPARE Stm FROM #Drop_Stm;
EXECUTE Stm;
DEALLOCATE PREPARE Stm;

You can do that in one command with MySQL:
drop table myprefix_1, myprefix_2, myprefix_3;
You'll probably have to build the table list dynamically in code though.
An alternative approach would be to use the general purpose routine library for MySQL 5.

I just wanted to post the exact SQL I used - it's something of a mixture of the top 3 answers:
SET GROUP_CONCAT_MAX_LEN=10000;
SET #del = (
SELECT CONCAT('DROP TABLE ', GROUP_CONCAT(TABLE_NAME), ';')
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'database_name'
AND TABLE_NAME LIKE 'prefix_%'
);
PREPARE stmt FROM #del;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

I found that the prepared statements were a little tricky to get working for me but setting the GROUP_CONCAT_MAX_LEN was essential when you have a lot of tables. This resulted in a simple three-step process with cut-and paste from the mysql command line that worked great for me:
SET GROUP_CONCAT_MAX_LEN=10000;
SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' )
AS statement FROM information_schema.tables
WHERE table_name LIKE 'myprefix_%';
Then carefully cut-and-paste the resulting long DROP statement.

Related

Add column to MySQL (not MariaDB) table only if it does not exist using SQL only

I have read this question and the solutions but they are more or less not applicable to my case. I have only SQL option and the PROCEDURE should be avoided, we may not have the required permission.
This is a SQL script that creates missing tables, columns and indexes etc. (schema update)
I see that in MariaDB we can use IF NOT EXISTS clause but this is not available in MySQL. Is there any similar way or workaround available in MySQL?
Using the IF() in a SET statement to come up with the logic works for me:
SET #s = (SELECT IF(
(SELECT COUNT(1)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'your_table'
AND table_schema = 'your_schema'
AND column_name = 'column_name'
) > 0,
"SELECT 1",
"ALTER TABLE your_table ADD column_name VARCHAR(100)"
));
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Is there a easy way to rename a table in procedure?

I am using MariaDB 10.1 SQLyog 11.5
I've renamed the table using below query.
ALTER TABLE old_name RENAME new_name
But there are many stored procedures that reference 'old_name'. I've opened all the SP creation query and changed. Because I don't know which SP has a query that reference old_name table.
Is there a way to know which SP has queries that reference old_name table?
By this INFORMATION_SCHEMA.ROUTINES you can fetch the text available in the stored procedure
Please could try this query: (not verified)
SELECT ROUTINE_NAME
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%old_name%'
-- AND ROUTINE_TYPE = "PROCEDURE" -- Filter only if need SPs
ORDER BY ROUTINE_NAME;
Reference from this page
You can it do like this:
Create RENAME Query
SELECT CONCAT ('RENAME TABLE ',
GROUP_CONCAT(t.TABLE_SCHEMA,'.',t.TABLE_NAME,' TO ', t.TABLE_SCHEMA,'.',REPLACE(t.TABLE_NAME,'old','NEW') SEPARATOR ' , ')
) INTO #sql
FROM information_schema.TABLES t
WHERE t.TABLE_TYPE = 'BASE TABLE'
AND t.TABLE_SCHEMA IN ('SCHEMA1','SCHEMA2')
AND t.TABLE_NAME LIKE 'old_table%';
ONLY to verify
SELECT #sql;
Prepare and execute it
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

How to remove all MySQL tables from the command-line without DROP database permissions? [duplicate]

This question already has answers here:
MySQL DROP all tables, ignoring foreign keys
(26 answers)
Closed 9 years ago.
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.
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;
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.
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.
You can drop the database and then recreate it with the below:-
mysql> drop database [database name];
mysql> create database [database name];
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';"

Command to drop all columns in a database that have prefix test_ to run

How I can run a command in phpMyAdmin which will drop all columns in a database that have the prefix test_.
To drop a column from a table, use the syntax:
alter table <tablename> drop column <columnname>
To find all the columns in a table in a database that start with test_, do the following:
select column_name
from INFORMATION_SCHEMA.columns
where table_name = <table_name> and
table_schema = <schema_name> and
left(column_name, 5) = 'test_' -- not using "like" because '_' is a wildcard char
If you were doing this manually, I would recommend running the following query and then pasting the results in to a mysql query interface:
select concat('alter table ', table_name, ' drop column ', column_name)
from INFORMATION_SCHEMA.columns
where table_name = <table_name> and
schema_name = <schema_name> and
left(column_name, 5) = 'test_'
You can do something similar in code, by running the query, returning the results and then running each row as a query.
If you actually want to drop the columns from your schema, you will need to generate the necessary SQL commands dynamically from MySQL's information schema tables. Whilst it is possible to do that within a MySQL stored procedure using SQL prepared statements, which I demonstrate below, you may well find it easier to implement/understand in your preferred development language (which you do not mention in your question):
DELIMITER ;;
CREATE PROCEDURE dropMatchingColumns(IN pattern VARCHAR(64))
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE cur CURSOR FOR
SELECT CONCAT(
'ALTER TABLE `', REPLACE( TABLE_NAME, '`', '``'), '` ',
GROUP_CONCAT(
'DROP COLUMN `', REPLACE(COLUMN_NAME, '`', '``'), '`'
)
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE pattern AND TABLE_SCHEMA = DATABASE()
GROUP BY TABLE_NAME
;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO #sql;
IF done THEN
LEAVE read_loop;
END IF;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur;
END;;
DELIMITER ;
With this procedure defined, one need only CALL dropMatchingColumns('test\_%'); in order to drop all the columns prefixed with test_ from the current database.
If you have MySQl Workbench then you can delete multiple columns by simply do a mass selection and telling workbench to do a mass deletion of the selected columns
I would like to explain or simplify this answer for those like me who were having trouble with this.
I was having trouble dropping a column with the name 'seq' in all tables in my database 'demo'.
You can create a selection with the commands formatted for each table using something like this:
Select concat('alter table ', table_name, ' drop column ', 'seq;')
from (select table_name
from INFORMATION_SCHEMA.tables
where table_name = table_name and
table_schema = 'demo') as t
This creates the alter table command for each table in the 'demo' database.
You have to select the result, copy it, and paste it back into the query editor.
It's a two step process, but if you have to do this several times, save the commands in a text file to run again later.

MySQL Dropping Tables

What syntax for MySQL would I use to drop multiple tables that have a similar pattern to them? Something like:
DROP TABLES FROM `Database1` LIKE "SubTable*"
Since DROP TABLE was supported by prepared statements, it can be done in this way -
SET #tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO #tables FROM information_schema.tables
WHERE table_schema = 'Database1' AND table_name LIKE 'SubTable%';
SET #tables = CONCAT('DROP TABLE ', #tables);
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
As noted on this question, the responses given here (Angelin and Devart) won't work in all circumstances without first increasing the limit of group_concat, as per below:
SET group_concat_max_len = 1024 * 1024 * 10;
No. But you can select tables names from information_schema database:
select table_name
from information_schema.tables
where table_schema = 'Database1'
and table_name like 'SubTable%'
And after that iterate the table names in result set and drop them
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;