Обрезать все таблицы в базе данных MySQL одной командой?
Существует ли запрос (команда) для усечения всех таблиц в базе данных за одну операцию? Я хочу знать, смогу ли я сделать это с помощью одного запроса.
30 ответов
Отбросить (т.е. удалить таблицы)
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
SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES where table_schema in ('db1_name','db2_name');
Используйте Query Result для усечения таблиц
Примечание: возможно, вы получите эту ошибку:
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
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;
Я нашел это, чтобы удалить все таблицы в базе данных:
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=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');
- Чтобы обрезать таблицу, необходимо удалить ограничения внешнего ключа, сопоставленные столбцам в этой таблице, из других таблиц (фактически для всех таблиц в конкретной БД / схеме).
- Таким образом, все ограничения внешнего ключа должны быть сначала удалены, а затем усечены таблицы.
- При желании используйте таблицу оптимизации (в mysql, innodb engine esp), чтобы вернуть используемое пространство / размер данных в ОС после усечения данных.
После усечения данных снова создайте те же ограничения внешнего ключа в той же таблице. Ниже приведен скрипт, который будет генерировать скрипт для выполнения вышеуказанных операций.
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) Нет необходимости отбрасывать и воссоздавать БД / Схему с той же структурой
Недостатки. 1) Ограничения FK должны быть именами в таблице с именем, содержащим "FK" в имени ограничения.
Вот мой вариант иметь "один оператор для усечения их всех".
Во-первых, я использую отдельную базу данных с именем '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 ;
Как только у вас есть эта хранимая процедура в вашей базе данных утилит, вы можете назвать ее как
call util.trunctables('nameofdatabase');
что сейчас ровно одно утверждение:-)
При использовании 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.
Здесь я знаю здесь
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']);
}
?>
проверить детали здесь ссылка
This worked for me. Change database, username and password accordingly.
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
Нет. Нет единой команды для усечения всех таблиц mysql одновременно. Вам нужно будет создать небольшой скрипт для усечения таблиц по очереди.
ссылка: http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html
Ans by battousaix идеален! Я просто использовал его ответ и создал последнюю рабочую команду для усечения таблиц базы данных.
mysql -P 3306 -h YOUR_HOST_HERE -u YOUR_USERNAME_HERE -pYOUR_PASSWORD_HERE -Nse 'show tables' DATABASE_NAME | while read table; do mysql -P 3306 -h YOUR_HOST_HERE -u YOUR_USERNAME_HERE -pYOUR_PASSWORD_HERE -e "SET FOREIGN_KEY_CHECKS = 0; truncate table $table" DATABASE_NAME; done
Вышеупомянутая команда отлично подойдет для сервера MySQL.
Кроме того, он включен.
УСТАНОВИТЬ FOREIGN_KEY_CHECKS = 0
Я обнаружил, что 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'''
Я знаю, что это не совсем одна команда, но желаемый результат может быть достигнут из phpMyAdmin, выполнив следующие действия:
- Выберите (все) таблицы, которые нужно удалить (Отметить все)
- Выберите "Удалить" / "Обрезать" из списка "С выбранным:"
- На странице подтверждения ("Вы действительно хотите:") скопируйте запрос (все с красным фоном)
- Перейдите вверх и нажмите на SQL и напишите: "SET FOREIGN_KEY_CHECKS=0;" затем вставьте ранее скопированный запрос
- Нажмите "Перейти"
Идея состоит в том, чтобы быстро получить все таблицы из базы данных (что вы делаете за 5 секунд и 2 клика), но сначала отключить проверку внешнего ключа. Нет CLI и нет удаления базы данных и добавления ее снова.
Вот процедура, которая должна обрезать все таблицы в локальной базе данных.
Дайте мне знать, если это не сработает, и я удалю этот ответ.
Непроверенные
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.
Вот решение, основанное на верхнем ответе, который я связал. Это решение безопасно обрабатывает аутентификацию без необходимости:
- Введите пароль для каждой таблицы
- Беспокойство о утечке пароля где-нибудь
- Побочные эффекты в других MySQL
cnf
файлы (~/.my.cnf
Для получения дополнительных сведений о том, что делают эти файлы, ознакомьтесь с разделом ресурсов внизу этого ответа.
1. Создайте локальный файл .my.cnf.
vi .temp.my.cnf
[client]
user=<admin_user_goes_here>
password=<admin_password_goes_here>
2. Обрежьте или удалите все таблицы.
2.A Truncate All Tables (только пустые)
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
Ресурсы:
Одиночная команда 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`;
Мы можем написать сценарий 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"
}
Вы можете заменить переменные env своими данными MySQL. Используя одну команду, вы можете обрезать все таблицы в БД.
Небольшое дополнение к ответу @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>;
mysqldump -u root -p --no-data dbname > schema.sql
mysqldump -u root -p drop dbname
mysqldump -u root -p < schema.sql
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. Эти команды должны быть запущены из командной строки следующим образом.
Замечания:
Я храню свои учетные данные в моем файле ~/.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"
- утверждение_экстернальной_системы зависит от утверждения_просмотра
- адрес зависит от клиента
- идентификатор клиента зависит от клиента
- external_id зависит от клиента
- учетные данные зависят от клиента
- адрес электронной почты зависит от клиента
- утверждение_запроса зависит от клиента
- 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
- Адрес усеченной таблицы
- Усеченная таблица opy_external_system
- Усеченный стол Approval_request
- Усеченный стол страна
- Учетные данные усеченной таблицы
- Усеченный стол заказчика
- Усеченный стол
- Усеченный стол 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
Я не уверен, но я думаю, что есть одна команда, с помощью которой вы можете скопировать схему базы данных в новую базу данных, как только вы это сделаете, вы можете удалить старую базу данных, а после этого вы можете снова скопировать схему базы данных в старое имя.
Солн 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
Следующий запрос 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
Идея может быть просто удалить и воссоздать таблицы?
РЕДАКТИРОВАТЬ:
@ Джонатан Леффлер: Правда
Другое предложение (или если вам не нужно обрезать ВСЕ таблицы):
Почему бы просто не создать базовую хранимую процедуру для усечения определенных таблиц
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.