Чи є запит (команда) для врізання всіх таблиць у базі даних за одну операцію? Я хочу знати, чи можу я це зробити за допомогою одного запиту.
Чи є запит (команда) для врізання всіх таблиць у базі даних за одну операцію? Я хочу знати, чи можу я це зробити за допомогою одного запиту.
Відповіді:
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
Додавання крапки до крапки з комою полегшує використання, наприклад, зсередини робочої версії 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
Корисно, якщо ви обмежені хостинговим рішенням (не можете скинути цілу базу даних).
Я змінив його для врізання таблиць. Не існує "--add-усікання таблиці" для mysqldump, тому я зробив:
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) Не потрібно скидати та відтворювати БД / схему з однаковою структурою
Недоліки. 1) обмеження FK повинні бути іменами в таблиці з назвою, що містить "FK" у назві обмеження.
якщо використовується sql сервер 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 ;
Після того, як ви збережете цю процедуру у вашій базі даних утиліт, ви можете її назвати так
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;
Я вважаю, що 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, виконавши наступні кроки:
Ідея полягає в тому, щоб швидко отримати всі таблиці з бази даних (що ви робите за 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:
Переконайтеся, що ви перебуваєте в оболонці. Ці команди слід виконати з командного рядка наступним чином.
Примітка:
Я зберігаю свої облікові дані у своєму файлі ~ / .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 сам створить єдиний запит, який буде усікати всі таблиці в даній базі даних. Він обходить зовнішні клавіші:
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
Soln 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
Ідея може бути просто скинути та відтворити таблиці?
Редагувати:
@Jonathan Leffler: Правда
Інші пропозиції (або випадок, якщо вам не потрібно врізати ВСІ таблиці):
Чому б просто не створити основну збережену процедуру для обрізання конкретних таблиць
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.