如何用一个命令在MySQL数据库中清空所有表格?

411

是否有一条查询(命令)可以在一次操作中截断数据库中的所有表?我想知道是否可以用一条单独的查询来完成这个任务。


2
清空所有表格?你是指清空数据库中所有表格的所有列吗?这是哪种查询语言?(例如SQL,MySQL,Oracle,Postgres等) - Jay
我不确定我会建议这样做,因为你很容易陷入麻烦。你不能只编写脚本并运行脚本吗? - GrayWizardx
谢谢回复,但我之所以不使用脚本是因为时间紧迫,所以想在MySQL中运行查询。 - devang
你可以使用游标与Information_Schema。不确定MySql是否支持Information_Schema.Tables,但应该是支持的。 - GrayWizardx
显示剩余5条评论
31个回答

1

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

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. address 依赖于 customer
  3. customer_identification 依赖于 customer
  4. external_id 依赖于 customer
  5. credential 依赖于 customer
  6. email_address 依赖于 customer
  7. approval_request 依赖于 customer
  8. customer_status 依赖于 customer
  9. customer_image 依赖于 customer

列出表格和行数:

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. 清空外部系统审批表
  3. 清空审批请求表
  4. 清空国家表
  5. 清空凭证表
  6. 清空客户表
  7. 清空客户身份验证表
  8. 清空客户图像表
  9. 清空客户状态表

确认操作成功:

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

解决方案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,并忽略了所有其他表格。 - Stephen Smith
1
可能会出现secure-file-priv错误。这是一种安全功能,只允许写入特定目录。在MySQL中输入此命令:show variables LIKE "secure_file_priv"; 它将显示您可以写入的文件夹。在我的情况下,它是/var/lib/mysql-files/。使用它来代替/tmp--只需确保您要写入的文件名不在该文件夹中即可。或者,您可以在[mysql]块中放置此行:secure-file-priv=''并重新启动MySQL来禁用它。但是,如果您这样做,您将关闭一层安全性。 - Jeff Clayton

0
以下的MySQL查询语句会生成一个单独的查询,将清空给定数据库中的所有表格。它可以绕过外键约束:
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

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


1
mysqldump -uuser -ppassword --no-data salesLeadsBrittany >salesLeadsTemplate.sql 这将创建一个仅包含模式(无数据)的SQL文件。您可以在此命令后删除数据库,并通过导入模式重新创建数据库。 - GJ.

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

这实际上是一个非常好的解决方案 :) - Csongor Fagyal

0

对@Mathias Bynens的回答进行小补充。当我运行此代码时,由于外键检查而出现了错误。

mysql -Nse 'SHOW TABLES' <database_name> | while read table; do mysql -e "SET FOREIGN_KEY_CHECKS=0; DROP TABLE $table" <database_name>; done

如果数据库中存在视图,则会返回错误。我必须手动清除视图,使用命令drop view <view_name>;

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详细信息替换环境变量。使用一个命令,您可以清空数据库中的所有表。


0
最近我碰巧需要清空数据库中所有以指定名称前缀开头的表格。
(export MYSQL_PWD=the_password; dbNameMatch="the_database_name_prefix%"; databaseList=$(mysql -u root -Nse "SHOW DATABASES LIKE '$dbNameMatch'"); for dbName in $databaseList; do mysql -uroot -Nse 'show tables' "$dbName" | while read table; do mysql -uroot -e "truncate table \`$table\`" "$dbName" & done; done)

这个单行命令对我有效。希望对你有帮助。

-1

一个想法是直接删除并重新创建表格?

编辑:

@Jonathan Leffler:没错

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

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

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

这会导致表上的所有约束、权限、视图等全部丢失,这是一个相当麻烦的问题。 - Jonathan Leffler
你可以执行删除,然后重新设置所有表而不是截断。我认为标记下降是出于沮丧。只需恢复备份即可。 - Mark Redman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接