MySQL DROP all tables, ignoring foreign keys

2019-01-09 21:04发布

Is there a nice easy way to drop all tables from a MySQL database, ignoring any foreign key constraints that may be in there?

21条回答
beautiful°
2楼-- · 2019-01-09 21:22

This solution is based on @SkyLeach answer but with the support of dropping tables with foreign keys.

echo "SET FOREIGN_KEY_CHECKS = 0;" > ./drop_all_tables.sql
mysqldump --add-drop-table --no-data -u user -p dbname | grep 'DROP TABLE' >> ./drop_all_tables.sql
echo "SET FOREIGN_KEY_CHECKS = 1;" >> ./drop_all_tables.sql
mysql -u user -p dbname < ./drop_all_tables.sql
查看更多
戒情不戒烟
3楼-- · 2019-01-09 21:24

You can do:

select concat('drop table if exists ', table_name, ' cascade;')
  from information_schema.tables;

Then run the generated queries. They will drop every single table on the current database.

Here is some help on drop table command.

查看更多
狗以群分
4楼-- · 2019-01-09 21:24

A one liner to drop all tables from a given database:

echo "DATABASE_NAME"| xargs -I{} sh -c "mysql -Nse 'show tables' {}| xargs -I[] mysql -e 'SET FOREIGN_KEY_CHECKS=0; drop table []' {}"

Running this will drop all tables from database DATABASE_NAME.

And a nice thing about this is that the database name is only written explicitly once.

查看更多
Luminary・发光体
5楼-- · 2019-01-09 21:25

Here is an automated way to do this via a bash script:

host=$1
dbName=$2
user=$3
password=$4

if [ -z "$1" ]
then
    host="localhost"
fi

# drop all the tables in the database
for i in `mysql -u$user -p$password $dbName -e "show tables" | grep -v Tables_in` ; do  echo $i && mysql -u$user -p$password $dbName -e "SET FOREIGN_KEY_CHECKS = 0; drop table $i ; SET FOREIGN_KEY_CHECKS = 1" ; done
查看更多
戒情不戒烟
6楼-- · 2019-01-09 21:26

I found the generated set of drop statements useful, and recommend these tweaks:

  1. Limit the generated drops to your database like this:
SELECT concat('DROP TABLE IF EXISTS `', table_name, '`;')
FROM information_schema.tables
WHERE table_schema = 'MyDatabaseName';

Note: This does not execute the DROP statements, it just gives you a list of them. You will need to cut and paste the output into your SQL engine to execute them.

  1. Note, per http://dev.mysql.com/doc/refman/5.5/en/drop-table.html, dropping with cascade is pointless / misleading:

"RESTRICT and CASCADE are permitted to make porting easier. In MySQL 5.5, they do nothing."

Therefore, in order for the drop statements to work if you need:

SET FOREIGN_KEY_CHECKS = 0

This will disable referential integrity checks - so when you are done performing the drops you need, you will want to reset key checking with

SET FOREIGN_KEY_CHECKS = 1
  1. The final execution should look like:
SET FOREIGN_KEY_CHECKS = 0;
-- Your semicolon separated list of DROP statements here
SET FOREIGN_KEY_CHECKS = 1;

NB: to use output of SELECT easier, mysql -B option can help.

查看更多
混吃等死
7楼-- · 2019-01-09 21:29

I use the following with a MSSQL server:

if (DB_NAME() = 'YOUR_DATABASE') 
begin
    while(exists(select 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE='FOREIGN KEY'))
    begin
         declare @sql nvarchar(2000)
         SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
         FROM information_schema.table_constraints
         WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
         exec (@sql)
         PRINT @sql
    end

    while(exists(select 1 from INFORMATION_SCHEMA.TABLES))
    begin
         declare @sql2 nvarchar(2000)
         SELECT TOP 1 @sql2=('DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']')
         FROM INFORMATION_SCHEMA.TABLES
        exec (@sql2)
        PRINT @sql2
    end
end
else
    print('Only run this script on the development server!!!!')

Replace YOUR_DATABASE with the name of your database or remove the entire IF statement (I like the added safety).

查看更多
登录 后发表回答