在一个命令中截断MySQL数据库中的所有表?

是否有一个查询(命令)在一个操作中截断数据库中的所有表? 我想知道如果我可以做一个单一的查询。

下降(即删除表)

mysql -Nse 'show tables' DATABASE_NAME | while read table; do mysql -e "drop table $table" DATABASE_NAME; done 

截断(即空表)

 mysql -Nse 'show tables' DATABASE_NAME | while read table; do mysql -e "truncate table $table" DATABASE_NAME; done 

在Mysql实例上截断多个数据库表

 SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES where table_schema in ('db1_name','db2_name'); 

使用查询结果截断表

注意:可能是你会得到这个错误:

 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails 

发生这种情况时,如果有表的外键引用您正试图放下/截断的表。

截断表之前所有你需要做的是:

 SET FOREIGN_KEY_CHECKS=0; 

截断你的表并将其改回

 SET FOREIGN_KEY_CHECKS=1; 

以这种方式使用phpMyAdmin:

数据库视图=>全选(表格)=>空

如果你想忽略外键检查,你可以取消勾选这个框:

[]启用外键检查

你需要运行至less4.5.0或更高版本来获得这个checkbox。

它不是MySQL CLI-fu,但嘿,它的工作原理!

MS SQL Server 2005+(删除打印实际执行…)

 EXEC sp_MSforeachtable 'PRINT ''TRUNCATE TABLE ?''' 

如果您的数据库平台支持INFORMATION_SCHEMA视图,请采取以下查询的结果并执行它们。

 SELECT 'TRUNCATE TABLE ' + TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 

试试这个MySQL的:

 SELECT Concat('TRUNCATE TABLE ', TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES 

在Concat中添加一个分号可以使它更容易使用,例如从mysql工作台中使用。

 SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES 

我发现这将删除数据库中的所有表:

 mysqldump -uUSERNAME -pPASSWORD --add-drop-table --no-data DATABASENAME | grep ^DROP | mysql -uUSERNAME -pPASSWORD DATABASENAME 

如果您受限于托pipe解决scheme(不能删除整个数据库),则有用。

我修改它截断表。 对于mysqldump没有“–add truncate-table”,所以我做了:

 mysqldump -uUSERNAME -pPASSWORD --add-drop-table --no-data DATABASENAME | grep ^DROP | sed -e 's/DROP TABLE IF EXISTS/TRUNCATE TABLE/g' | mysql -uUSERNAME -pPASSWORD DATABASENAME 

为我工作 – 编辑,修正最后一个命令中的拼写错误

这将打印命令截断所有表:

 SELECT GROUP_CONCAT(Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME) SEPARATOR ';') FROM INFORMATION_SCHEMA.TABLES where table_schema in ('my_db'); 
  1. 要截断表,必须从其他表中删除映射到此表中列的外键约束(事实上,在特定DB / Schema中的所有表上)。
  2. 所以,所有的外键约束必须首先被删除,然后是表截断。
  3. 数据截断后,可以使用优化表(在mysql,innodb engine esp中)将已使用的数据空间/大小回收到操作系统。
  4. 一旦数据截断被执行,在同一个表上再次创build相同的外键约束。 请参阅下面的脚本,该脚本将生成执行上述操作的脚本。

     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 '\n'; 

现在,运行生成的Db Truncate.sql脚本

优点。 1)回收磁盘空间2)不需要删除并重新创build具有相同结构的DB / Schema

缺点。 1)FK约束应该是表中名称在约束名称中包含“FK”的名称。

如果使用sql server 2005,则有一个隐藏的存储过程,允许您针对数据库内的所有表执行一个命令或一组命令。 这里是你如何使用这个存储过程调用TRUNCATE TABLE

 EXEC [sp_MSforeachtable] @command1="TRUNCATE TABLE ?" 

这是一个很好的文章,进一步阐述。

但是,对于MySql,可以使用mysqldump并指定--add-drop-tables--no-data选项来删除并创build所有表,忽略数据。 喜欢这个:

 mysqldump -u[USERNAME] -p[PASSWORD] --add-drop-table --no-data [DATABASE] 

来自dev.mysql的mysqldump使用指南

使用这个和形成查询

 SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES where table_schema in (db1,db2) INTO OUTFILE '/path/to/file.sql'; 

现在使用这个来使用这个查询

 mysql -u username -p </path/to/file.sql 

如果你得到这样的错误

 ERROR 1701 (42000) at line 3: Cannot truncate a table referenced in a foreign key constraint 

最简单的方法是在文件顶部添加这一行

 SET FOREIGN_KEY_CHECKS=0; 

其中说我们不想检查外键约束,而通过这个文件。

它将截断数据库db1和bd2中的所有表。

不,没有一个命令可以一次截断所有的mysql表。 您将不得不创build一个小脚本来逐个截断表格。

ref: http : //dev.mysql.com/doc/refman/5.0/en/truncate-table.html

我发现最简单的做法就是像下面的代码一样,用你自己的代替表名。 重要的是确保最后一行总是SET FOREIGN_KEY_CHECKS = 1;

 SET FOREIGN_KEY_CHECKS=0; TRUNCATE `table1`; TRUNCATE `table2`; TRUNCATE `table3`; TRUNCATE `table4`; TRUNCATE `table5`; TRUNCATE `table6`; TRUNCATE `table7`; SET FOREIGN_KEY_CHECKS=1; 

我发现TRUNCATE TABLE ..在外键约束上有问题,甚至在NOCHECK CONSTRAINT ALL之后,所以我使用了DELETE FROM语句。 这确实意味着身份种子不会重置,您可以随时添加DBCC CHECKIDENT来实现此目的。

我使用下面的代码打印出消息窗口中的sql截断数据库中的所有表,然后再运行它。 这使得犯了一个错误有点难。

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

在这里,我知道这里

  SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES where table_schema in ('databasename1','databasename2'); 

如果不能删除或更新父行:外键约束失败

发生这种情况时,如果有表的外键引用您正试图放下/截断的表。

截断表之前所有你需要做的是:

 SET FOREIGN_KEY_CHECKS=0; 

截断你的表并将其改回

 SET FOREIGN_KEY_CHECKS=1; 

用户这个PHP代码

  $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']); } ?> 

点击这里查看链接

我不确定,但我认为有一个命令可以将数据库模式复制到新的数据库中,一旦完成了这个操作,您可以删除旧的数据库,然后再次将数据库模式复制到旧的名称。

这是一个过程,应该截断本地数据库中的所有表。

让我知道如果它不起作用,我会删除这个答案。

未经testing

 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中实现所需的结果:

  1. select要删除的(全部)表格(全部选中)
  2. 从“With selected:”列表中select“Drop”/“Truncate”
  3. 在确认页面(“您确实想要:”)复制查询(红色背景的所有内容)
  4. 去顶部,点击SQL,并写入:“SET FOREIGN_KEY_CHECKS = 0;” 然后粘贴以前复制的查询
  5. 点击“开始”

这个想法是快速从数据库中获取所有的表(5秒钟和2次点击),但是先禁用外键检查。 没有CLI,不删除数据库,并再次添加。

 TB=$( mysql -Bse "show tables from DATABASE" ); for i in ${TB}; do echo "Truncating table ${i}"; mysql -e "set foreign_key_checks=0; set unique_checks=0;truncate table DATABASE.${i}; set foreign_key_checks=1; set unique_checks=1"; sleep 1; done 

大卫,

感谢您抽出时间格式化代码,但这是应该如何应用的。

-Kurt

在UNIX或Linux上:

确保你在一个bash shell。 这些命令将从命令行运行,如下所示。

注意:

我将我的凭据存储在我的〜/ .my.cnf文件中,所以我不需要在命令行上提供它们。

注意:

cpm是数据库名称

我只是从每个命令中只显示一小部分结果。

find你的外键约束:

 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. approval_external_system依赖于approval_request
  2. 地址取决于客户
  3. customer_identification取决于客户
  4. external_id取决于客户
  5. 凭证取决于客户
  6. email_address取决于客户
  7. approval_request取决于客户
  8. customer_status取决于客户
  9. customer_image取决于客户

列出表格和行数:

 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 

截断你的表格:

 klarsen@Chaos:~$ TB=$( mysql -Bse "show tables from cpm" ); for i in ${TB}; do echo "Truncating table ${i}"; mysql -e "set foreign_key_checks=0; set unique_checks=0;truncate table cpm.${i}; set foreign_key_checks=1; set unique_checks=1"; sleep 1; done 
  1. 截断表地址
  2. 截断表approval_external_system
  3. 截断表approval_request
  4. 截断表国家
  5. 截断表格凭证
  6. 截断表客户
  7. 截断表customer_identification
  8. 截断表customer_image
  9. 截断表customer_status

validation它的工作:

 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是数据库名称

 C:\>for /F "tokens=*" %a IN ('mysql -Bse "show tables" cpm') do mysql -e "set foreign_key_checks=0; set unique_checks=0; truncate table %a; foreign_key_checks=1; set unique_checks=1" cpm 

下面的MySQL查询本身将产生一个查询,它将截断给定数据库中的所有表。 它绕过FOREIGN键:

 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 
 mysqldump -u root -p --no-data dbname > schema.sql mysqldump -u root -p drop dbname mysqldump -u root -p < schema.sql 

Soln 1)

 mysql> select group_concat('truncate',' ',table_name,';') from information_schema.tables where table_schema="db_name" into outfile '/tmp/a.txt'; mysql> /tmp/a.txt; 

Soln 2)

 - Export only structure of a db - drop the database - import the .sql of structure 

– 编辑—-

 earlier in solution 1, i had mentioned concat() instead of group_concat() which would have not returned the desired result 

这是我的变种“有一个声明截断他们所有”。

首先,我为我的助手存储过程使用了一个名为'util'的单独数据库。 我的存储过程截断所有表的代码是:

 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数据库中有这个存储过程,就可以这样调用它

 call util.trunctables('nameofdatabase'); 

这现在正是一个声明:-)

 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; 

一个想法可能是只删除和重新创build表?

编辑:

@Jonathan Leffler:的确如此

其他build议 (或者你不需要截断所有表):

为什么不创build一个基本的存储过程来截断特定的表

 CREATE PROCEDURE [dbo].[proc_TruncateTables] AS TRUNCATE TABLE Table1 TRUNCATE TABLE Table2 TRUNCATE TABLE Table3 GO 
 <?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 info和TABLE_NAME。