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

whhtz7ly  于 2021-06-23  发布在  Mysql
关注(0)|答案(27)|浏览(367)

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

mfuanj7w

mfuanj7w16#

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

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
inn6fuwd

inn6fuwd17#

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

yzuktlbb18#

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

g6baxovj19#

使用它并形成查询

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

avkwfej4

avkwfej420#

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

h79rfbju21#

我发现这样可以删除数据库中的所有表:

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

对我来说很有用——编辑,修复最后一个命令中的错误

hm2xizp9

hm2xizp922#

一个想法可以是把table扔下来重新制作?
编辑:
@乔纳森:是的
其他建议(或不需要截断所有表的情况):
为什么不创建一个基本的存储过程来截断特定的表呢

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

g2ieeal723#

下面是一个应该截断本地数据库中所有表的过程。
如果不起作用,请告诉我,我将删除此答案。
未经测试

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;
33qvvth1

33qvvth124#

我发现最简单的方法就是执行下面的代码,用自己的表名替换表名。重要信息:确保最后一行始终设置为foreign\u key\u 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;
mzmfm0qo

mzmfm0qo25#

我们可以编写如下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变量。使用一个命令可以截断数据库中的所有表。

lrl1mhuk

lrl1mhuk26#

下面是我的变体,它有一个语句来截断所有的语句。
首先,我为助手存储过程使用一个名为“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');

现在正好是一句话:-)

weylhg0b

weylhg0b27#

要截断一个表,必须从其他表(实际上是特定db/schema中的所有表)中删除Map到此表中的列的外键约束。
因此,首先必须删除所有外键约束,然后进行表截断。
(可选)使用optimize表(在mysql、innodb engine esp中)在数据截断后将使用的数据空间/大小回收到os。
一旦执行了数据截断,就在同一个表上再次创建相同的外键约束。请参阅下面的脚本,该脚本将生成执行上述操作的脚本。

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

相关问题