用一条命令截断MySQL数据库中的所有表?


346

是否有一个查询(命令)以一次操作截断数据库中的所有表?我想知道是否可以通过一个查询来做到这一点。


1
截断所有表?您是说要截断数据库中所有表的所有列?这是什么查询语言?(例如SQL,MySQL,Oracle,Postgres等)
杰伊

我不确定我会建议这样做,因为这样很容易使您陷入麻烦。您为什么不能只编写截断脚本并运行脚本,这是有原因的吗?
GrayWizardx

谢谢4的答复,但唯一的理由不脚本它正在运行的时间不足,所以想在mysql中运行查询
devang

ya在mysql..and中的查询含义类似于截断表table_name ..在这里,我想在一个查询中截断db中所有表的所有行
devang

您可以将Information_Schema与游标一起使用。不确定MySql,但它应该支持Information_Schema.Tables
GrayWizardx

Answers:


340

删除(即删除表)

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

17
是的,干净。但是您可能需要使用-uUSER -pPASSWORD运行它。如果您在级联上删除了FK,也可能必须多次运行它。
mihaicc 2012年

47
如果遇到FK问题,例如“ 无法删除或更新父行:外键约束失败 ”,请确保通过修改以下命令来禁用外键检查:mysql -e "SET FOREIGN_KEY_CHECKS = 0; drop table $table" DATABASE_NAME
Ethan P.

24
无需循环mysql客户端。像这样循环播放:mysql -Nse 'show tables' DATABASE_NAME | while read table; do echo "drop table $table;"; done | mysql DATABASE_NAME
Alexander Shcheblikin

2
@TylerCollier您需要一个.my.cnf
Felix Eve

2
基于上面的答案和评论,由于它们无法满足我的预期,我制作了一个简单的bash脚本,您可以将其用于此目的。您可以在以下网址
mocanuga

145

截断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;

1
如果您有数据库的用户名和密码,并且不想在外壳中显式地键入它们,这可能是最好的解决方案。
巴赫(Bach)

5
赞成,因为此解决方案仅需要数据库访问而不是SSH访问。此外,它与操作系统无关。
mastazi '17

@mastazi我有几个问题:1.“ table_schema”代表什么?是从模式名称中站立吗?2.TABLE_NAME代表什么?它代表应该删除的表吗?3.我应该在要删除的表上写上“('db1_name','db2_name')”之类的命令吗?
AAEM

@Ahmed唯一需要的替换是您必须用数据库名称替换db1_name和db2_name。然后,您必须复制该查询的结果,并将其粘贴为新的mysql查询并执行。INFORMATION_SCHEMA是一个内置模式,该模式预先安装在每个MySQL安装中,并且包含有关您的数据库的信息,请不要触摸它,否则您的MySQL将开始出现异常:-) table_schema和table_name是表中称为“ TABLES”的列information_schema
mastazi '18

用“ db_name”表示模式的名称?我只有1个要删除其表数据的架构
AAEM

66

以这种方式使用phpMyAdmin:

数据库视图=>检查所有(表)=>空

如果要忽略外键检查,则可以取消选中显示以下内容的框:

[]启用外键检查

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

它不是MySQL CLI-fu,但是,它可以工作!


31
谁说我们正在运行PHP ...?
jsh

37
谁说我们没有?这个答案显然对人们有用。它有助于。
bzeaman 2015年

2
如果您具有父子数据库架构,则此方法将不起作用。
卡里·邦多克

2
外键约束失败。
Brian Hannay

2
@BrianHannay它是2015年6月在PMA 4.5.0中添加的。我找到了变更 日志原始问题
Nemo

24

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

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

嗨..谢谢d的回复,我尝试了此查询,但似乎不起作用..是诸如截断表table_name之类的东西,我可以将其用于数据库中的所有表
。– devang

我忘记了MySQL不直接支持“ +”运算符。假设这是错误,我在上面添加了CONCAT()示例。如果仍然收到错误消息,请共享实际的错误消息。
海滩

此查询有效,但是如果我有一个差异数据库名称,例如devang ..是我的数据库名称,那么如果我根据您的上述查询使用它,则会引发foll错误。表'devang.TABLES'不存在
devang

3
啊 INFORMATION_SCHEMA是活动数据库中存在的视图。如果更改数据库,则将对该数据库执行视图。更改数据库时无需修改查询。只需执行以下步骤:1)更改活动数据库。2)运行脚本。3)复制结果4)将结果粘贴回编辑器5)执行结果。现在,活动数据库中的所有表都被截断了。
海滩

1
谨防!这将选择所有数据库中的所有表(即使不是当前数据库中的表。MySQL示例也不起作用,但是在我的情况下,它返回了293行(表)而不是66行。想象一下数据丢失...
f4der 2014年

19

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

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

如果您受托管解决方案的限制(无法删除整个数据库)很有用。

我修改了它以截断表。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

对我有用--edit,在最后一个命令中修正了错字


15
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;

如果要使用当前数据库(从而使此代码可移植),请将以下条件更改SELECT为:AND table_schema = DATABASE();
alx

它对我来说并不截断。MySQL 5.7.25
Lucas Bustamante

14

我发现最简单的方法就是执行下面的代码,只需将表名替换为您自己的即可。 重要的是确保最后一行始终为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;

7
您不必重复SET FOREIGN_KEY_CHECKS = 0;在刚开始的每条TRUNCATE命令之后,它将模式标记为0
HMagdy 2015年

12

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

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

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

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

好处。1)回收磁盘空间2)无需删除并重新创建具有相同结构的DB / Schema

缺点。1)FK约束应为表中的名称,且约束名称中的名称应包含“ FK”。


3

如果使用sql server 2005,则有一个隐藏的存储过程,使您可以对数据库中的所有表执行一个或一组命令。这是TRUNCATE TABLE使用此存储过程调用的方式:

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

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

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

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

来自dev.mysql的mysqldump使用指南


3

使用它并形成查询

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中的所有表。


数据库名称应使用qoutes
Roman M


2

这是我的变体,其中有一个语句可以截断“全部”。

首先,我为助手存储过程使用了一个名为“ 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');

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


2

因为我知道这里

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

    }
?>

在此处查看详细信息 链接


1

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

让我知道它是否无效,我将删除此答案。

未经测试

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;

花了我很多时间弄清楚为什么它不起作用。.然后,对该电子邮件线程的评论有所帮助:forums.mysql.com/read.php?61,116597,219343#msg - 219343-供参考:“不幸的是,它看起来像准备的语句不能在游标一起使用从手册:dev.mysql.com/doc/refman/6.0/en/...
Tominator

1

我发现即使在NOCHECK CONSTRAINT ALL之后,TRUNCATE TABLE ..仍存在外键约束问题,因此我改用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'''

0

我不确定,但是我认为有一个命令可用于将数据库的架构复制到新数据库中,一旦完成此操作,便可以删除旧数据库,然后再将数据库架构复制到旧名称。


1
mysqldump -uuser -ppassword --no-data salesLeadsBrittany> salesLeadsT​​emplate.sql这将创建仅具有模式(无数据)的sql文件。您可以在此命令后删除数据库,并可以通过导入架构来重新创建数据库。
GJ。

0

我知道这不完全是一个命令,但是可以按照以下步骤从phpMyAdmin中实现所需的结果:

  1. 选择要删除的(所有)表(全部选中)
  2. 从“已选择:”列表中选择“拖放” /“截断”
  3. 在确认页面(“您真的要:”上)复制查询(所有带有红色背景的内容)
  4. 转到顶部,单击SQL并输入:“ SET FOREIGN_KEY_CHECKS = 0;” 然后粘贴先前复制的查询
  5. 点击“开始”

这样做的想法是从数据库中快速获取所有表(您在5秒钟和2次单击中完成),但首先禁用外键检查。没有CLI,也没有删除数据库并再次添加它。


0
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

-

大卫,

感谢您抽出宝贵的时间来格式化代码,但这是应该采用的方式。

-库尔特

在UNIX或Linux机器上:

确保您在bash shell中。这些命令将从命令行运行,如下所示。

注意:

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

注意:

cpm是数据库名称

我仅显示每个命令的结果的一小部分。

找到您的外键约束:

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. customer_identification取决于客户
  4. external_id取决于客户
  5. 凭证取决于客户
  6. email_address取决于客户
  7. 审批请求取决于客户
  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. 截断表rovaling_external_system
  3. 截断表批准_请求
  4. 截桌国家
  5. 截断表凭证
  6. 截台客户
  7. 截断表格customer_identification
  8. 截断表格customer_image
  9. 截断表格customer_status

验证它是否有效:

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

0

下面的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

0
mysqldump -u root -p --no-data dbname > schema.sql
mysqldump -u root -p drop dbname
mysqldump -u root -p < schema.sql

0

索恩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;

索恩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

1
这似乎只返回第一个表:TRUNCATE table1,而忽略了所有其他表。
史蒂芬·史密斯

这个解决方案肯定是疯狂的。我不知道为什么没有投票。可能是因为我的错误已被编辑。
Angelin Nadar 2014年

0

这对我有用。相应地更改数据库,用户名和密码。

mysql -Nse 'show tables' -D DATABASE -uUSER -pPWD | while read table; do echo "SET FOREIGN_KEY_CHECKS = 0;drop table \`$table\`;SET FOREIGN_KEY_CHECKS = 1;"; done | mysql DATABASE -uUSER -pPWD


-1

一个想法可能只是删除并重新创建表?

编辑:

@乔纳森·莱夫勒:是的

其他建议(或者您不需要截断所有表的情况):

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

CREATE PROCEDURE [dbo].[proc_TruncateTables]
AS
TRUNCATE TABLE Table1
TRUNCATE TABLE Table2
TRUNCATE TABLE Table3
GO

这会丢失表上的所有约束,权限,视图等,这是一个相当大的麻烦。
乔纳森·莱夫勒

您可以执行删除操作,然后重新设置所有表的种子而不是截断。我认为降价是出于无奈。只需还原您的备份即可。
Mark Redman

-5
<?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信息和TABLE_NAME。


嘿詹姆斯,我认为OP首先要寻找一个班轮..其次是要删除所有表并删除它们的命令。这需要某种用户干预。尽管感谢您的帖子
克雷格·韦恩
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.