在一个命令中截断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');
- 要截断表,必须从其他表中删除映射到此表中列的外键约束(事实上,在特定DB / Schema中的所有表上)。
- 所以,所有的外键约束必须首先被删除,然后是表截断。
- 数据截断后,可以使用优化表(在mysql,innodb engine esp中)将已使用的数据空间/大小回收到操作系统。
-
一旦数据截断被执行,在同一个表上再次创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中实现所需的结果:
- select要删除的(全部)表格(全部选中)
- 从“With selected:”列表中select“Drop”/“Truncate”
- 在确认页面(“您确实想要:”)复制查询(红色背景的所有内容)
- 去顶部,点击SQL,并写入:“SET FOREIGN_KEY_CHECKS = 0;” 然后粘贴以前复制的查询
- 点击“开始”
这个想法是快速从数据库中获取所有的表(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"
- approval_external_system依赖于approval_request
- 地址取决于客户
- customer_identification取决于客户
- external_id取决于客户
- 凭证取决于客户
- email_address取决于客户
- approval_request取决于客户
- customer_status取决于客户
- 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
- 截断表地址
- 截断表approval_external_system
- 截断表approval_request
- 截断表国家
- 截断表格凭证
- 截断表客户
- 截断表customer_identification
- 截断表customer_image
- 截断表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。