MySQL删除所有表,忽略外键

有没有一个简单的方法来删除MySQL数据库中的所有表,忽略可能在那里的任何外键约束?

我发现生成的一组drop语句很有用,并推荐这些调整:

  1. 将生成的drop限制在你的数据库中,如下所示:
 SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') FROM information_schema.tables WHERE table_schema = 'MyDatabaseName'; 
  1. 请注意,根据http://dev.mysql.com/doc/refman/5.5/en/drop-table.html ,级联丢弃是毫无意义/误导性的:

“RESTRICT和CASCADE允许移植更容易,在MySQL 5.5中,它们什么也不做。

因此,为了使drop语句在您需要时能够正常工作:

 SET FOREIGN_KEY_CHECKS = 0 

这将禁用引用完整性检查 – 所以当你完成你需要的滴时,你会想重置键检查

 SET FOREIGN_KEY_CHECKS = 1 

http://www.devdaily.com/blog/post/mysql/drop-mysql-tables-in-any-order-foreign-keys

 SET FOREIGN_KEY_CHECKS = 0; drop table if exists customers; drop table if exists orders; drop table if exists order_details; SET FOREIGN_KEY_CHECKS = 1; 

(请注意,这将回答如何禁用外键检查,以便能够以任意顺序删除表,而不回答如何为所有现有表自动生成drop-table语句并在单个脚本中执行它们。确实。)

这里是SurlyDre的存储过程修改,以便外键被忽略:

 DROP PROCEDURE IF EXISTS `drop_all_tables`; DELIMITER $$ CREATE PROCEDURE `drop_all_tables`() BEGIN DECLARE _done INT DEFAULT FALSE; DECLARE _tableName VARCHAR(255); DECLARE _cursor CURSOR FOR SELECT table_name FROM information_schema.TABLES WHERE table_schema = SCHEMA(); DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE; SET FOREIGN_KEY_CHECKS = 0; OPEN _cursor; REPEAT FETCH _cursor INTO _tableName; IF NOT _done THEN SET @stmt_sql = CONCAT('DROP TABLE ', _tableName); PREPARE stmt1 FROM @stmt_sql; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; END IF; UNTIL _done END REPEAT; CLOSE _cursor; SET FOREIGN_KEY_CHECKS = 1; END$$ DELIMITER ; call drop_all_tables(); DROP PROCEDURE IF EXISTS `drop_all_tables`; 

这是一个基于游标的解决scheme。 有点冗长,但作为一个单一的SQL批处理:

 DROP PROCEDURE IF EXISTS `drop_all_tables`; DELIMITER $$ CREATE PROCEDURE `drop_all_tables`() BEGIN DECLARE _done INT DEFAULT FALSE; DECLARE _tableName VARCHAR(255); DECLARE _cursor CURSOR FOR SELECT table_name FROM information_schema.TABLES WHERE table_schema = SCHEMA(); DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE; OPEN _cursor; REPEAT FETCH _cursor INTO _tableName; IF NOT _done THEN SET @stmt_sql = CONCAT('DROP TABLE ', _tableName); PREPARE stmt1 FROM @stmt_sql; EXECUTE stmt1; DEALLOCATE PREPARE stmt1; END IF; UNTIL _done END REPEAT; CLOSE _cursor; END$$ DELIMITER ; call drop_all_tables(); DROP PROCEDURE IF EXISTS `drop_all_tables`; 

从这个答案 ,

执行:

  use `dbName`; --your db name here SET FOREIGN_KEY_CHECKS = 0; SET @tables = NULL; SET GROUP_CONCAT_MAX_LEN=32768; SELECT GROUP_CONCAT('`', table_schema, '`.`', table_name, '`') INTO @tables FROM information_schema.tables WHERE table_schema = (SELECT DATABASE()); SELECT IFNULL(@tables, '') INTO @tables; SET @tables = CONCAT('DROP TABLE IF EXISTS ', @tables); PREPARE stmt FROM @tables; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET FOREIGN_KEY_CHECKS = 1; 

这将从当前正在使用的数据库中删除表。 您可以使用use来设置当前数据库。


否则,Dion接受的答案是比较简单的,除了你需要执行两次,第一个得到查询,第二个执行查询。 我提供了一些愚蠢的反勾号来转义数据库和表名中的特殊字符。

  SELECT CONCAT('DROP TABLE IF EXISTS `', table_schema, '`.`', table_name, '`;') FROM information_schema.tables WHERE table_schema = 'dbName'; --your db name here 

你可以做:

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

然后运行生成的查询。 他们将放弃当前数据库中的每个表。

这里是drop table命令的一些帮助。

我在Dion Truter的答案中提出了这个修改,使许多表更容易:

 SET GROUP_CONCAT_MAX_LEN = 10000000; SELECT CONCAT('SET FOREIGN_KEY_CHECKS=0;\n', GROUP_CONCAT(CONCAT('DROP TABLE IF EXISTS `', table_name, '`') SEPARATOR ';\n'), ';\nSET FOREIGN_KEY_CHECKS=1;') FROM information_schema.tables WHERE table_schema = 'SchemaName'; 

这将在一个字段中返回整个事件,因此您可以复制一次并删除所有表(在工作台中使用Copy Field Content (unquoted) )。 如果你有很多表,你可能会在GROUP_CONCAT()上遇到一些限制。 如果是这样,请增加最大lenvariables(如果需要,还可以增加max_allowed_packet )。

如果在linux(或任何其他支持pipe道,回声和grep的系统),你可以用一行:

 echo "SET FOREIGN_KEY_CHECKS = 0;" > temp.txt; \ mysqldump -u[USER] -p[PASSWORD] --add-drop-table --no-data [DATABASE] | grep ^DROP >> temp.txt; \ echo "SET FOREIGN_KEY_CHECKS = 1;" >> temp.txt; \ mysql -u[USER] -p[PASSWORD] [DATABASE] < temp.txt; 

我知道这是一个古老的问题,但我认为这种方法是快速和简单的。

上面的每一个方法都包含比这一个AFAICT更多的工作…

 ( mysqldump --add-drop-table --no-data -u root -p database | grep 'DROP TABLE' ) > ./drop_all_tables.sql mysql -u root -p database < ./drop_all_tables.sql 

这里是一个通过bash脚本来做到这一点的自动化方法:

 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 

在PHP中,它很容易:

 $pdo = new PDO('mysql:dbname=YOURDB', 'root', 'root'); $pdo->exec('SET FOREIGN_KEY_CHECKS = 0'); $query = "SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') FROM information_schema.tables WHERE table_schema = 'YOURDB'"; foreach($pdo->query($query) as $row) { $pdo->exec($row[0]); } $pdo->exec('SET FOREIGN_KEY_CHECKS = 1'); 

只要记住将YOURDB更改为您的数据库的名称,显然是用户/通行证。

在像bash / zsh这样的Linux shell中:

 DATABASE_TO_EMPTY="your_db_name"; { echo "SET FOREIGN_KEY_CHECKS = 0;" ; \ mysql "$DATABASE_TO_EMPTY" --skip-column-names -e \ "SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') \ FROM information_schema.tables WHERE table_schema = '$DATABASE_TO_EMPTY';";\ } | mysql "$DATABASE_TO_EMPTY" 

这将生成命令,然后立即pipe道他们到第二个客户端实例将删除表。

聪明的一点当然是从这里的其他答案复制 – 我只是想复制和粘贴一行(ISH),实际上 OP的工作。

当然,除非你有一个非常低的安全设置,否则你将不得不把你的凭证放在这些mysql命令中(两次)。 (或者你可以别名你的mysql命令来包含你的信用)。

这是一个很老的post,但这里的答案都没有真正回答我这个问题,所以我希望我的post能够帮助人们!

我在另一个问题上find了这个解决scheme,对我来说真的很好:

 mysql -Nse 'show tables' DB_NAME | while read table; do mysql -e "SET FOREIGN_KEY_CHECKS=0; truncate table \`$table\`" DB_NAME; done 

这实际上会清空数据库DB_NAME中的所有表,而不仅仅显示TRUNCATE命令行。

希望这可以帮助!

一个class轮从一个给定的数据库中删除所有表:

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

运行此操作将删除数据库DATABASE_NAME中的所有表。

而关于这一点的好处是数据库名称只写明确一次。

在@Dion Truter和@Wade Williams的基础上,下面的shell脚本将首先显示它将要运行的内容,并给你一个使用Ctrl-C中止的机会。

 #!/bin/bash DB_HOST=xxx DB_USERNAME=xxx DB_PASSWORD=xxx DB_NAME=xxx CMD="mysql -sN -h ${DB_HOST} -u ${DB_USERNAME} -p${DB_PASSWORD} ${DB_NAME}" # Generate the drop statements TMPFILE=/tmp/drop-${RANDOM}.sql echo 'SET FOREIGN_KEY_CHECKS = 0;' > ${TMPFILE} ${CMD} $@ >> ${TMPFILE} << ENDD SELECT concat('DROP TABLE IF EXISTS \`', table_name, '\`;') FROM information_schema.tables WHERE table_schema = '${DB_NAME}'; ENDD echo 'SET FOREIGN_KEY_CHECKS = 1;' >> ${TMPFILE} # Warn what we are about to do echo cat ${TMPFILE} echo echo "Press ENTER to proceed (or Ctrl-C to abort)." read # Run the SQL echo "Dropping tables..." ${CMD} $@ < ${TMPFILE} echo "Exit status is ${?}." rm ${TMPFILE} 

我使用以下MSSQL服务器:

 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!!!!') 

将YOUR_DATABASEreplace为数据库的名称或删除整个IF语句(我喜欢增加的安全性)。

最好的解决scheme ,迄今为止

select数据库 – >右键单击 – >任务 – >生成脚本 – 将打开用于生成脚本的向导。 在“设置脚本”选项中select对象后,单击“ 高级button” 。 在“脚本删除和创build”下select脚本删除

运行脚本。