Truncate all tables in a MySQL database in one command?
是否有一个查询(命令)在一个操作中截断数据库中的所有表?我想知道我是否可以用一个查询来完成这项工作。
删除(即删除表格)
1 |
截断(即空表)
1 |
在MySQL实例上截断多个数据库表
1 2 |
使用查询结果截断表
注:可能你会得到这个错误:
1 |
如果有表具有对要删除/截断的表的外键引用,则会发生这种情况。
在截断表之前,您需要做的就是:
1 |
截断表并将其改回
1 |
以这种方式使用phpmyadmin:
Database View => Check All (tables) => Empty
如果要忽略外键检查,可以取消选中显示以下内容的框:
[ ] Enable foreign key checks
您需要至少运行4.5.0或更高版本才能获得此复选框。
它不是mysql的cli-fu,但是嘿,它工作了!
MS SQL Server 2005+(删除打印以实际执行…)
1 | EXEC sp_MSforeachtable 'PRINT ''TRUNCATE TABLE ?''' |
如果您的数据库平台支持信息模式视图,请获取以下查询的结果并执行它们。
为MySQL尝试此操作:
向concat中添加分号可以更容易地使用,例如,在mysql工作台中使用分号。
我发现这是为了删除数据库中的所有表:
1 |
如果您受到托管解决方案的限制(无法删除整个数据库),则非常有用。
我修改了它以截断表。mysqldump没有"--add truncate table",所以我这样做了:
1 |
为我工作--编辑,修复最后一个命令中的拼写错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | SET FOREIGN_KEY_CHECKS = 0; SELECT @str := CONCAT('TRUNCATE TABLE ', table_schema, '.', table_name, ';') FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema IN ('db1_name','db2_name'); PREPARE stmt FROM @str; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET FOREIGN_KEY_CHECKS = 1; |
这将打印截断所有表的命令:
1 |
我发现最简单的方法就是执行下面的代码,用自己的表名替换表名。重要事项确保最后一行始终设置外键检查=1;
1 2 3 4 5 6 7 8 9 |
执行数据截断后,在同一个表上再次创建相同的外键约束。请参阅下面的脚本,该脚本将生成用于执行上述操作的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 | SELECT CONCAT('ALTER TABLE ',TABLE_SCHEMA,'.',TABLE_NAME,' DROP FOREIGN KEY ',CONSTRAINT_NAME,';') FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY' AND TABLE_SCHEMA='<TABLE SCHEMA>' UNION SELECT CONCAT('TRUNCATE TABLE ',TABLE_SCHEMA,'.',TABLE_NAME,';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='<TABLE SCHEMA>' AND TABLE_TYPE='BASE TABLE' UNION SELECT CONCAT('OPTIMIZE TABLE ',TABLE_SCHEMA,'.',TABLE_NAME,';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='<TABLE SCHEMA>' AND TABLE_TYPE='BASE TABLE' UNION SELECT CONCAT('ALTER TABLE ',TABLE_SCHEMA,'.',TABLE_NAME,' ADD CONSTRAINT ',CONSTRAINT_NAME,' FOREIGN KEY(',COLUMN_NAME,')',' REFERENCES ',REFERENCED_TABLE_NAME,'(',REFERENCED_COLUMN_NAME,');') FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE CONSTRAINT_NAME LIKE 'FK%' AND TABLE_SCHEMA='<TABLE SCHEMA>' INTO OUTFILE"C:/DB Truncate.sql" LINES TERMINATED BY ' '; |
现在,运行生成的db truncate.sql脚本
好处。1)回收磁盘空间2)不需要删除和重新创建具有相同结构的数据库/架构
缺点。1)fk约束应该是表中的名称,约束名称中包含"fk"。
使用此项并形成查询
1 2 3 |
现在使用这个来使用这个查询
1 |
如果你遇到这样的错误
1 |
最简单的方法是在文件的顶部添加此行
1 |
也就是说,我们不想在浏览这个文件时检查外键约束。
它将截断数据库db1和bd2中的所有表。
如果使用SQL Server 2005,则有一个隐藏的存储过程,允许您对数据库中的所有表执行一个命令或一组命令。下面是使用此存储过程调用
1 | EXEC [sp_MSforeachtable] @command1="TRUNCATE TABLE ?" |
这是一篇很好的文章,详细阐述。
但是,对于MySQL,可以使用mysqldump并指定
dev.mysql中的mysqldump使用指南
不,没有一个命令可以同时截断所有mysql表。您必须创建一个小脚本来逐个截断表。
参考:http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html
我知道我在这里
1 2 |
如果不能删除或更新的行:a parent key约束条fails
那事如果有证明人与对外表两个表的钥匙,你是想滴/附加。
截断表之前,所有你需要做的是:两个
1 |
你的桌子和附加两个换回来
1 |
PHP代码的用户。
1 2 3 4 5 6 7 8 | $truncate = mysql_query("SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';') as tables_query FROM INFORMATION_SCHEMA.TABLES where table_schema in ('databasename')"); while($truncateRow=mysql_fetch_assoc($truncate)){ mysql_query($truncateRow['tables_query']); } ?> |
在这里检查的零售 链接
这里是我的变体,它有"one语句来截断'em all'。
首先,我正在为助手存储过程使用一个名为"util"的单独数据库。截断所有表的存储过程代码是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | DROP PROCEDURE IF EXISTS trunctables; DELIMITER ;; CREATE PROCEDURE trunctables(theDb varchar(64)) BEGIN declare tname varchar(64); declare tcursor CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_type <> 'VIEW' AND table_schema = theDb; SET FOREIGN_KEY_CHECKS = 0; OPEN tcursor; l1: LOOP FETCH tcursor INTO tname; if tname = NULL then leave l1; end if; set @sql = CONCAT('truncate `', theDB, '`.`', tname, '`'); PREPARE stmt from @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END LOOP l1; CLOSE tcursor; SET FOREIGN_KEY_CHECKS = 1; END ;; DELIMITER ; |
一旦在UTIL数据库中有了这个存储过程,就可以像这样调用它
1 |
这正是一个声明:—)
我发现那个截断表……使用外键约束有困难,即使在nocheck约束all之后,我还是使用delete from语句。这意味着标识种子不会重置,您可以始终添加一个DBCC CHECKIDENT来实现这一点。
在运行SQL之前,我使用下面的代码将截断数据库中所有表的SQL输出到消息窗口。这只会让犯错误变得更加困难。
1 2 3 | EXEC sp_MSforeachtable 'PRINT ''ALTER TABLE ? NOCHECK CONSTRAINT ALL''' EXEC sp_MSforeachtable 'print ''DELETE FROM ?''' EXEC sp_MSforeachtable 'print ''ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all''' |
下面是一个应该截断本地数据库中所有表的过程。
如果不起作用,请通知我,我将删除此答案。
未经测试的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | CREATE PROCEDURE truncate_all_tables() BEGIN -- Declare local variables DECLARE done BOOLEAN DEFAULT 0; DECLARE cmd VARCHAR(2000); -- Declare the cursor DECLARE cmds CURSOR FOR SELECT CONCAT('TRUNCATE TABLE ', TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES; -- Declare continue handler DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1; -- Open the cursor OPEN cmds; -- Loop through all rows REPEAT -- Get order number FETCH cmds INTO cmd; -- Execute the command PREPARE stmt FROM cmd; EXECUTE stmt; DROP PREPARE stmt; -- End of loop UNTIL done END REPEAT; -- Close the cursor CLOSE cmds; END; |
我不确定,但我认为有一个命令可以用来将数据库的模式复制到新的数据库中,一旦完成此操作,就可以删除旧的数据库,然后再将数据库模式复制到旧名称中。
我知道这不是一个命令,但是通过以下步骤可以从phpmyadmin中获得所需的结果:
其思想是快速从数据库中获取所有表(您只需5秒钟和2次单击即可完成),但首先禁用外键检查。没有cli,也没有删除数据库并再次添加。
1 2 3 4 5 6 |
——
戴维
感谢您花时间来格式化代码,但这是应用代码的方式。
-库尔特
在Unix或Linux设备上:
确保你是在一个巴什壳。这些命令将从命令行运行,如下所示。
注:
我将我的凭证存储在~/.my.cnf文件中,因此不需要在命令行上提供它们。
注:
cpm是数据库名称
我只显示每个命令的一小部分结果样本。
查找外键约束:
1 2 3 4 | klarsen@Chaos:~$ mysql -Bse"select concat(table_name, ' depends on ', referenced_table_name) from information_schema.referential_constraints where constraint_schema = 'cpm' order by referenced_table_name" |
列出表和行计数:
1 2 3 4 5 6 7 8 9 10 11 | klarsen@Chaos:~$ mysql -Bse"SELECT table_name, table_rows FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'cpm'" | cat -n 1 address 297 2 approval_external_system 0 3 approval_request 0 4 country 189 5 credential 468 6 customer 6776 7 customer_identification 5631 8 customer_image 2 9 customer_status 13639 |
截断表:
1 |
验证它是否有效:
1 2 3 4 5 6 7 8 9 10 11 12 | klarsen@Chaos:~$ mysql -Bse"SELECT table_name, table_rows FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'cpm'" | cat -n 1 address 0 2 approval_external_system 0 3 approval_request 0 4 country 0 5 credential 0 6 customer 0 7 customer_identification 0 8 customer_image 0 9 customer_status 0 10 email_address 0 |
在Windows框中:
注:
cpm是数据库名称
1 |
下面的mysql查询本身将生成一个查询,该查询将截断给定数据库中的所有表。它绕过了外键:
1 2 3 4 5 6 7 8 | SELECT CONCAT( 'SET FOREIGN_KEY_CHECKS=0; ', GROUP_CONCAT(dropTableSql SEPARATOR '; '), '; ', 'SET FOREIGN_KEY_CHECKS=1;' ) as dropAllTablesSql FROM ( SELECT Concat('TRUNCATE TABLE ', table_schema, '.', TABLE_NAME) AS dropTableSql FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'DATABASE_NAME' ) as queries |
1 2 3 |
索恩1)
1 2 |
索恩2)
--编辑----
1 | earlier in solution 1, i had mentioned concat() instead of group_concat() which would have not returned the desired result |
一个想法可能是直接删除并重新创建表?
编辑:
@乔纳森·莱弗勒:对
其他建议(或不需要截断所有表的情况):
为什么不创建一个基本的存储过程来截断特定的表呢?
1 2 3 4 5 6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php // connect to database $conn=mysqli_connect("localhost","user","password","database"); // check connection if (mysqli_connect_errno()) { exit('Connect failed: '. mysqli_connect_error()); } // sql query $sql =mysqli_query($conn,"TRUNCATE" . TABLE_NAME); // Print message if ($sql === TRUE) { echo 'data delete successfully'; } else { echo 'Error: '. $conn->error; } $conn->close(); ?> |
这是我用来清除表的代码段。只需更改$conn信息和表名。