是否有一个很好的简单的方法来删除MySQL数据库中的所有表,忽略任何外键约束,可能在那里?
当前回答
谷歌主题总是把我带到这个SO问题,所以这里是工作的mysql代码,删除表和视图:
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_sql1 = CONCAT('DROP TABLE IF EXISTS ', _tableName);
SET @stmt_sql2 = CONCAT('DROP VIEW IF EXISTS ', _tableName);
PREPARE stmt1 FROM @stmt_sql1;
PREPARE stmt2 FROM @stmt_sql2;
EXECUTE stmt1;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt1;
DEALLOCATE PREPARE stmt2;
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`;
其他回答
下面是修改后的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`;
这是一个基于游标的解决方案。有点长,但可以作为单个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`;
从命令行中删除所有的表:
mysqldump -u [user_name] -p[password] -h [host_name] --add-drop-table --no-data [database_name] | grep ^DROP | mysql -u [user_name] -p[password] -h [host_name] [database_name]
其中[user_name]、[password]、[host_name]和[database_name]需要替换为真实的数据(用户、密码、主机名、数据库名)。
我发现生成的drop语句集很有用,并推荐以下调整:
将生成的drop限制在数据库中,如下所示:
SELECT concat('DROP TABLE IF EXISTS `', table_name, '`;')
FROM information_schema.tables
WHERE table_schema = 'MyDatabaseName';
注1:这并不执行DROP语句,它只是给你一个它们的列表。您需要将输出剪切并粘贴到SQL引擎中才能执行它们。
注2:如果你有视图,你必须手动将每个DROP TABLE ' VIEW_NAME '语句修改为DROP VIEW ' VIEW_NAME '。
注意,根据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
最终的执行应该是这样的:
SET FOREIGN_KEY_CHECKS = 0;
-- Your semicolon separated list of DROP statements here
SET FOREIGN_KEY_CHECKS = 1;
注意:要使用SELECT输出更容易,mysql -B选项可以帮助。
上面的每个方法都包含了比这个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
推荐文章
- 警告用户/local/mysql/data目录不属于mysql用户
- 添加一个复合主键
- 无法添加或更新子行:外键约束失败
- 如何从本地机器mysqldump远程数据库
- 如何正确地创建复合主键- MYSQL
- 仅在Datetime列上按日期分组
- 在MySQL数据库中存储货币值的最佳数据类型
- 如何自定义'显示进程列表'在mysql?
- MySQL删除一些外键
- 用MySQL LEFT JOIN删除行
- MySQL - length() vs char_length()
- 如何在Oracle SQL开发人员中找到引用给定表的表?
- 使用PDO进行行计数
- 在Mac上安装MySQL后,使用ALTER USER语句重置MySQL root密码
- my.cnf文件在macOS上的位置