是否存在在一次操作中截断数据库中所有表的查询(命令)?我想知道我是否可以用一个查询做到这一点。
如果使用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]
Mysqldump使用指南
MS SQL Server 2005+(删除打印以实际执行…)
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
一个想法可能只是删除并重新创建表?
编辑:
@Jonathan Leffler:没错
其他建议(或者你不需要截断所有表):
为什么不创建一个基本的存储过程来截断特定的表呢
CREATE PROCEDURE [dbo].[proc_TruncateTables]
AS
TRUNCATE TABLE Table1
TRUNCATE TABLE Table2
TRUNCATE TABLE Table3
GO
下面是一个截断本地数据库中所有表的过程。
如果它不起作用,请告诉我,我会删除这个答案。
未测试的
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;
不。没有单独的命令可以一次截断所有mysql表。您必须创建一个小脚本来逐个截断表。
裁判:http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html
以这种方式使用phpMyAdmin:
Database View => Check All (tables) =>空
如果你想忽略外键检查,你可以取消选中下面的复选框:
[]启用外键检查
您至少需要运行4.5.0或更高版本才能获得此复选框。
它不是MySQL CLI-fu,但是,嘿,它工作!
我发现这可以删除数据库中的所有表:
mysqldump -uUSERNAME -pPASSWORD --add-drop-table --no-data DATABASENAME | grep ^DROP | mysql -uUSERNAME -pPASSWORD DATABASENAME
如果您受到托管解决方案的限制(不能删除整个数据库),则非常有用。
我修改了它来截断表格。mysqldump没有“——add- trunct -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,修复最后一个命令的错别字
删除(即删除表格)
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
我发现TRUNCATE表..外键约束有问题,即使在NOCHECK约束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'''
To truncate a table, one must drop the foreign key constraints mapped to the columns in this table from other tables (in fact on all tables in the specific DB/Schema). So, all foreign key constraints must be dropped initially followed by table truncation. Optionally, use the optimize table (in mysql, innodb engine esp) to reclaim the used data space/size to OS after data truncation. Once data truncation is carried out, create the same foreign key constraints again on the same table. See below a script that would generate the script to carry out the above operations. 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”。
溶液(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
我知道这不是一个确切的命令,但预期的结果可以从phpMyAdmin通过以下步骤实现:
选择(所有)要删除的表(勾选全部) 从“With selected:”列表中选择“Drop”/“Truncate” 在确认页面(“Do you really want to:”)复制查询(所有带有红色背景的内容) 在顶部,点击SQL并写:“SET FOREIGN_KEY_CHECKS=0;”然后粘贴之前复制的查询 点击“去”
其思想是快速从数据库中获取所有表(只需5秒和2次单击),但首先禁用外键检查。不需要CLI,也不需要删除数据库并重新添加。
下面的查询将为Mysql模式中的所有数据库表生成一个截断命令列表。(将dbSchemaName1替换为您的Db模式名。)
SELECT CONCAT('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES WHERE table_schema IN ('dbSchemaName1','dbSchemaName2');
复制查询结果(可能看起来像下面这样),并将截断命令列表粘贴到MySQL Worbench或您选择的查询命令工具中的SQL查询选项卡中:
TRUNCATE TABLE dbSchemaName1.table1;
TRUNCATE TABLE dbSchemaName1.table2;
TRUNCATE TABLE dbSchemaName1.table3;
注意:您可能会收到以下错误:
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
如果存在外键引用您试图删除/截断的表的表,就会发生这种情况。
要解决在运行truncate命令之前关闭外键检查的问题:
SET FOREIGN_KEY_CHECKS=0; -- turn off foreign key checks
TRUNCATE TABLE dbSchemaName1.table1; -- truncate tables
TRUNCATE TABLE dbSchemaName1.table2;
TRUNCATE TABLE dbSchemaName1.table3;
SET FOREIGN_KEY_CHECKS=1; -- turn on foreign key checks
使用它并形成查询
SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES where table_schema in (db1,db2)
INTO OUTFILE '/path/to/file.sql';
现在使用this来使用这个查询
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中的所有表。
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"
Approval_external_system依赖于approval_request 地址视客户而定 Customer_identification取决于客户 External_id取决于客户 凭证取决于客户 Email_address取决于客户 Approval_request取决于客户 Customer_status取决于客户 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
截断表地址 截断表approval_external_system 截断表approval_request 截断表国家 截断表凭据 截断表客户 截断表customer_identification 截断表customer_image 截断表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
下面的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
mysqldump -u root -p --no-data dbname > schema.sql
mysqldump -u root -p drop dbname
mysqldump -u root -p < schema.sql
<?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。
我发现最简单的方法是像下面这样做,只需用自己的表名替换表名。重要的是确保最后一行永远是 设置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');
这是我的变体有'一个语句截断'他们所有'。
首先,我为我的辅助存储过程使用了一个名为“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, ';')作为table_query FROM INFORMATION_SCHEMA。table where table_schema in ('databasename')"); 而($ truncateRow =作用(截断)美元){ mysql_query()美元truncateRow [' tables_query ']); } ? > 查看详情 链接
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;
这对我很管用。修改数据库、用户名和密码。
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
我们可以编写如下所示的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细节替换env变量。使用一个命令就可以截断一个DB中的所有表。
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`;
由battousaix的Ans是完美的! 我只是使用了他的答案,并创建了截断数据库表的最终工作命令。
mysql -P 3306 -h YOUR_HOST_HERE -u YOUR_USERNAME_HERE -pYOUR_PASSWORD_HERE -Nse 'show tables' DATABASE_NAME |,同时读取表;-h YOUR_HOST_HERE -u your_username - here -pYOUR_PASSWORD_HERE -e "SET FOREIGN_KEY_CHECKS = 0;截断表$ DATABASE_NAME完成
上面的命令将完美地工作于MySQL服务器。
而且,它也包括在内。
设置foreign_key_checks = 0
我觉得最上面的答案太棒了。但是,当你有一个经过身份验证的MySQL数据库用户时,它就失败了。
这是建立在我链接的顶部答案之上的解决方案。此解决方案安全地处理身份验证,而无需:
为每个表输入密码 担心你的密码泄露到某个地方 对其他MySQL cnf文件(~/.my.cnf)的副作用要了解更多关于这些文件的详细信息,请查看答案底部的参考资料部分。
1. 创建本地。my.cnf文件
vi .temp.my.cnf
[client]
user=<admin_user_goes_here>
password=<admin_password_goes_here>
2. 截断或删除所有表
2.截断所有表(仅为空)
mysql --defaults-extra-file=.temp.my.cnf -Nse 'show tables' <db_name_goes_here> | while read table; do mysql --defaults-extra-file=.temp.my.cnf -e "truncate table $table" <db_name_goes_here>; done
2.B删除所有表(完全删除)
mysql --defaults-extra-file=.temp.my.cnf -Nse 'show tables' <db_name_goes_here> | while read table; do mysql --defaults-extra-file=.temp.my.cnf -e "drop table $table" <db_name_goes_here>; done
3.清理
删除用户密码文件
rm -rf .temp.my.cnf
资源:
https://rtcamp.com/tutorials/mysql/mycnf-preference/ https://dev.mysql.com/doc/refman/8.0/en/option-files.html https://dev.mysql.com/doc/refman/8.0/en/option-file-options.html#option_general_defaults-extra-file
给@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>手动清除视图;