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

dev*_*ang 327 mysql

是否有查询(命令)在一次操作中截断数据库中的所有表?我想知道我是否可以使用一个查询来执行此操作.

小智 327

删除(即删除表)

mysql -Nse 'show tables' DATABASE_NAME | while read table; do mysql -e "drop table $table" DATABASE_NAME; done
Run Code Online (Sandbox Code Playgroud)

截断(即空表)

mysql -Nse 'show tables' DATABASE_NAME | while read table; do mysql -e "truncate table $table" DATABASE_NAME; done
Run Code Online (Sandbox Code Playgroud)

  • 如果遇到FK问题,例如"_Cannot删除或更新父行:外键约束失败_",请确保通过修改命令来禁用外键检查,如下所示:`mysql -e"SET FOREIGN_KEY_CHECKS = 0; drop table $ table"DATABASE_NAME" (42认同)
  • 不需要循环mysql客户端.把它带出这样的循环:`mysql -Nse'显示表'DATABASE_NAME | 读表; 做echo"drop table $ table;"; 完成| mysql DATABASE_NAME` (23认同)
  • 是的,干净,ty.但您可能需要使用-uUSER -pPASSWORD运行它.如果您在级联上删除FK,也可能需要多次运行它. (16认同)
  • 你应该引用表名:..."truncate table \\`$ table \\`"... (5认同)
  • @TylerCollier你需要一个[.my.cnf](https://rtcamp.com/tutorials/mysql/mycnf-preference/) (2认同)
  • 基于上面的答案和评论,并且因为它们对我来说没有按预期工作,所以我制作了一个简单的 bash 脚本,您可以使用它。您可以在以下位置找到它:https://gist.github.com/mocanuga/eff26a3dcc40ef657a1c812f68511f6d (2认同)

小智 134

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

SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';') 
FROM INFORMATION_SCHEMA.TABLES where  table_schema in ('db1_name','db2_name');
Run Code Online (Sandbox Code Playgroud)

使用"查询结果"截断表

注意:您可能会收到此错误:

ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
Run Code Online (Sandbox Code Playgroud)

如果存在对您尝试删除/截断的表的外键引用的表,则会发生这种情况.

截断表之前您需要做的就是:

SET FOREIGN_KEY_CHECKS=0;
Run Code Online (Sandbox Code Playgroud)

截断表格并将其更改回

SET FOREIGN_KEY_CHECKS=1;
Run Code Online (Sandbox Code Playgroud)

  • Upvoted是因为此解决方案仅需要数据库访问而不需要SSH访问.此外,它独立于操作系统. (4认同)
  • 如何“使用查询结果”来截断表? (4认同)

Nem*_*emo 66

以这种方式使用phpMyAdmin:

数据库视图=>全部检查(表)=>清空

如果要忽略外键检查,可以取消选中以下框:

[]启用外键检查

您需要运行至少4.5.0或更高版本才能获得此复选框.

它不是MySQL CLI-fu,但是嘿,它有效!

  • 谁说我们没有?这个答案显然证明对人有用; 它有助于. (33认同)
  • 谁说我们在运行PHP ......? (28认同)
  • 如果您有父子数据库架构,这将不起作用. (2认同)
  • 外键约束失败. (2认同)
  • @BrianHannay它于2015年6月在PMA 4.5.0中添加.我找到了[changelog](https://github.com/phpmyadmin/history/blob/master/ChangeLogs/ChangeLog-2015#L165)和[原始问题] ](https://github.com/phpmyadmin/phpmyadmin/issues/6239) (2认同)

bea*_*ach 24

MS SQL Server 2005+(删除PRINT以实际执行......)

EXEC sp_MSforeachtable 'PRINT ''TRUNCATE TABLE ?'''
Run Code Online (Sandbox Code Playgroud)

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

SELECT 'TRUNCATE TABLE ' + TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
Run Code Online (Sandbox Code Playgroud)

试试MySQL吧:

SELECT Concat('TRUNCATE TABLE ', TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES
Run Code Online (Sandbox Code Playgroud)

在Concat中添加分号可以更容易地使用,例如在mysql工作台中使用.

SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES
Run Code Online (Sandbox Code Playgroud)

  • 啊.INFORMATION_SCHEMA是活动数据库中存在的视图.如果更改数据库,则将针对该数据库执行视图.更改数据库时无需修改查询.只需按照以下步骤操作:1)更改活动数据库.2)运行脚本.3)复制结果4)将结果粘贴回编辑器5)执行结果.现在,活动数据库中的所有表都被截断. (3认同)
  • 谨防!这将选择所有数据库中的所有表(甚至那些不在当前数据库中的表。MySQL 示例不起作用,但在我的情况下,它返回 293 行(表)而不是 66。想象一下数据丢失...... (2认同)

小智 19

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

mysqldump -uUSERNAME -pPASSWORD --add-drop-table --no-data DATABASENAME | grep ^DROP | mysql -uUSERNAME -pPASSWORD DATABASENAME
Run Code Online (Sandbox Code Playgroud)

如果您受托管解决方案的限制(无法删除整个数据库),则非常有用.

我修改它以截断表.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
Run Code Online (Sandbox Code Playgroud)

适合我 - 编辑,修复最后一个命令中的拼写错误


小智 13

我发现只需执行下面的代码就可以了,只需用自己的代码替换表名. 重要的是确保最后一行总是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;
Run Code Online (Sandbox Code Playgroud)

  • 你不必重复SET FOREIGN_KEY_CHECKS = 0; 在每个TRUNCATE命令之后,仅在起始行将模式标记为0 (7认同)

Gau*_*pta 13

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

SELECT GROUP_CONCAT(Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME) SEPARATOR ';') FROM INFORMATION_SCHEMA.TABLES where table_schema in ('my_db');
Run Code Online (Sandbox Code Playgroud)


Geo*_*oik 13

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;
Run Code Online (Sandbox Code Playgroud)


小智 5

  1. 要截断表,必须从其他表中删除映射到此表中列的外键约束(实际上在特定DB/Schema中的所有表上).
  2. 因此,必须首先删除所有外键约束,然后删除表截断.
  3. (可选)使用优化表(在mysql,innodb引擎esp中)在数据截断后将已使用的数据空间/大小回收到OS.
  4. 执行数据截断后,在同一个表上再次创建相同的外键约束.请参阅下面一个脚本,该脚本将生成执行上述操作的脚本.

    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';
    
    Run Code Online (Sandbox Code Playgroud)

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

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

缺点.1)FK约束应该是表中的名称,其名称在约束名称中包含"FK".


beb*_*bbo 5

这是我的变体,具有“一个语句来截断所有”。

首先,我为我的帮助存储过程使用一个名为“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 ;
Run Code Online (Sandbox Code Playgroud)

一旦你的 util 数据库中有这个存储过程,你就可以像这样调用它

call util.trunctables('nameofdatabase');
Run Code Online (Sandbox Code Playgroud)

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


Dos*_*tee 4

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

EXEC [sp_MSforeachtable] @command1="TRUNCATE TABLE ?"
Run Code Online (Sandbox Code Playgroud)

是一篇很好的文章,进一步阐述了这一点。

但是,对于 MySql,您可以使用 mysqldump 并指定--add-drop-tables--no-data选项来删除和创建所有忽略数据的表。像这样:

mysqldump -u[USERNAME] -p[PASSWORD] --add-drop-table --no-data [DATABASE]
Run Code Online (Sandbox Code Playgroud)

dev.mysql 的 mysqldump 使用指南