是否有一个查询(命令)以一次操作截断数据库中的所有表?我想知道是否可以通过一个查询来做到这一点。
是否有一个查询(命令)以一次操作截断数据库中的所有表?我想知道是否可以通过一个查询来做到这一点。
Answers:
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 -e "SET FOREIGN_KEY_CHECKS = 0; drop table $table" DATABASE_NAME
mysql -Nse 'show tables' DATABASE_NAME | while read table; do echo "drop table $table;"; done | mysql DATABASE_NAME
截断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:
数据库视图=>检查所有(表)=>空
如果要忽略外键检查,则可以取消选中显示以下内容的框:
[]启用外键检查
您需要运行的是至少4.5.0或更高版本,才能获得此复选框。
它不是MySQL CLI-fu,但是,它可以工作!
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
我发现这删除了数据库中的所有表:
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,在最后一个命令中修正了错字
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();
我发现最简单的方法就是执行下面的代码,只需将表名替换为您自己的即可。 重要的是确保最后一行始终为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;
这将打印命令以截断所有表:
SELECT GROUP_CONCAT(Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME) SEPARATOR ';') FROM INFORMATION_SCHEMA.TABLES where table_schema in ('my_db');
一旦执行了数据截断,请在同一表上再次创建相同的外键约束。参见下面的脚本,该脚本将生成执行上述操作的脚本。
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”。
如果使用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]
使用它并形成查询
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表。您将必须创建一个小脚本来逐个截断表。
参考:http : //dev.mysql.com/doc/refman/5.0/en/truncate-table.html
这是我的变体,其中有一个语句可以截断“全部”。
首先,我为助手存储过程使用了一个名为“ 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');
现在正好是一个声明:-)
因为我知道这里
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']);
}
?>
在此处查看详细信息 链接
这是一个应截断本地数据库中所有表的过程。
让我知道它是否无效,我将删除此答案。
未经测试
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;
我发现即使在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'''
我知道这不完全是一个命令,但是可以按照以下步骤从phpMyAdmin中实现所需的结果:
这样做的想法是从数据库中快速获取所有表(您在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
-
大卫,
感谢您抽出宝贵的时间来格式化代码,但这是应该采用的方式。
-库尔特
在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"
列出表和行数:
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
验证它是否有效:
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
索恩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
一个想法可能只是删除并重新创建表?
编辑:
@乔纳森·莱夫勒:是的
其他建议(或者您不需要截断所有表的情况):
为什么不创建基本的存储过程来截断特定表
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信息和TABLE_NAME。