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

时间:2009-12-16 06:58:41

标签: mysql

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

27 个答案:

答案 0 :(得分:319)

删除(即删除表格)

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

答案 1 :(得分:127)

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

答案 2 :(得分:62)

以这种方式使用phpMyAdmin:

  

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

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

  

[]启用外键检查

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

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

答案 3 :(得分:23)

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 workbench。

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

答案 4 :(得分:18)

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

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,在最后一个命令中修正拼写错误

答案 5 :(得分:12)

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;

答案 6 :(得分:11)

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

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

答案 7 :(得分:11)

我发现只需执行下面的代码,只需用自己的代码替换表名即可。 important 确保最后一行始终     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;

答案 8 :(得分:5)

  1. 要截断表,必须从其他表中删除映射到此表中列的外键约束(事实上,在特定DB / Schema中的所有表上)。
  2. 因此,必须首先删除所有外键约束,然后删除表截断。
  3. (可选)使用优化表(在mysql,innodb engine 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';
    
  5. 现在,运行生成的Db Truncate.sql脚本

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

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

答案 9 :(得分:3)

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

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

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

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

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

mysqldump usage guide from dev.mysql

答案 10 :(得分: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中的所有表。

答案 11 :(得分:2)

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

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

答案 12 :(得分: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']);

    }
?>

在这里查看详细信息 link

答案 13 :(得分: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;

答案 14 :(得分: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'''

答案 15 :(得分:1)

这是我的变体,有'一个声明来截断'全部'。

首先,我使用一个名为'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');

现在只是一个陈述: - )

答案 16 :(得分:0)

PHP单个命令:

php -r '$d="PUT_YOUR_DB_NAME_HERE"; $q="show tables"; $dt="drop table"; exec("mysql -Nse \"$q\" $d", $o); foreach($o as $e) `mysql -e "$dt $e" $d`;'

已执行的PHP脚本:

$d="PUT_YOUR_DB_NAME_HERE"; 
$q="show tables"; 
$dt="drop table"; 

exec("mysql -Nse \"$q\" $d", $o); 

foreach($o as $e)
  `mysql -e "$dt $e" $d`;

答案 17 :(得分:0)

我们可以编写如下的bash脚本

truncate_tables_in_mysql() {
    type mysql >/dev/null 2>&1 && echo "MySQL present." || sudo apt-get install -y mysql-client
    
    tables=$(mysql -h 127.0.0.1 -P $MYSQL_PORT -u $MYSQL_USER  -p$MYSQL_PASSWORD -e "USE $BACKEND_DATABASE;    
SHOW TABLES;")
    tables_list=($tables)
    
    query_string="USE $BACKEND_DATABASE; SET FOREIGN_KEY_CHECKS = 0;"
    for table in "${tables_list[@]:1}"
    do
        query_string="$query_string TRUNCATE TABLE \`$table\`; "
    done
    query_string="$query_string SET FOREIGN_KEY_CHECKS = 1;"
    
    mysql -h 127.0.0.1 -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PASSWORD -e "$query_string"
}

您可以用MySQL详细信息替换环境变量。使用一个命令,您可以截断数据库中的所有表。

答案 18 :(得分: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

答案 19 :(得分:0)

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

答案 20 :(得分: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

答案 21 :(得分: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

-

大卫,

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

-Kurt

在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. 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取决于客户
  10. 列出表格和行数:

    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
    10. 验证它是否有效:

      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
      

答案 22 :(得分:0)

我知道这不是一个命令,但是可以通过以下步骤在phpMyAdmin中实现所需的结果:

  1. 选择(所有)要删除的表(全部检查)
  2. 从“已选中:”列表
  3. 中选择“删除”/“截断”
  4. 在确认页面上(“你真的想:”)复制查询(红色背景下的所有内容)
  5. 转到顶部并单击SQL并写入:“SET FOREIGN_KEY_CHECKS = 0;”然后粘贴以前复制的查询
  6. 点击“开始”
  7. 我们的想法是快速获取数据库中的所有表(您在5秒内完成,然后单击2次),但首先禁用外键检查。没有CLI,也没有丢弃数据库并再次添加它。

答案 23 :(得分:0)

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

答案 24 :(得分:0)

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

答案 25 :(得分:-1)

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

修改

@Jonathan Leffler:是的

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

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

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

答案 26 :(得分:-6)

<?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。