Có một truy vấn (lệnh) để cắt tất cả các bảng trong cơ sở dữ liệu trong một hoạt động không? Tôi muốn biết nếu tôi có thể làm điều này với một truy vấn duy nhất.
Có một truy vấn (lệnh) để cắt tất cả các bảng trong cơ sở dữ liệu trong một hoạt động không? Tôi muốn biết nếu tôi có thể làm điều này với một truy vấn duy nhất.
Câu trả lời:
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
cắt ngắn nhiều bảng cơ sở dữ liệu trên cá thể Mysql
SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES where table_schema in ('db1_name','db2_name');
Sử dụng kết quả truy vấn để cắt bớt các bảng
Lưu ý: có thể bạn sẽ gặp lỗi này:
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
Điều đó xảy ra nếu có các bảng có tham chiếu khóa ngoài tới bảng mà bạn đang cố gắng thả / cắt.
Trước khi cắt bớt bảng Tất cả những gì bạn cần làm là:
SET FOREIGN_KEY_CHECKS=0;
Cắt bớt các bảng của bạn và thay đổi nó trở lại
SET FOREIGN_KEY_CHECKS=1;
Sử dụng phpMyAdmin theo cách này:
Chế độ xem cơ sở dữ liệu => Kiểm tra tất cả (bảng) => Trống
Nếu bạn muốn bỏ qua kiểm tra khóa ngoại, bạn có thể bỏ chọn hộp có nội dung:
[] Cho phép kiểm tra khóa ngoại
Bạn sẽ cần phải chạy ít nhất phiên bản 4.5.0 trở lên để có được hộp kiểm này.
Nó không phải MySQL CLI-fu, nhưng hey, nó hoạt động!
MS SQL Server 2005+ (Xóa PRINT để thực thi thực tế ...)
EXEC sp_MSforeachtable 'PRINT ''TRUNCATE TABLE ?'''
Nếu nền tảng cơ sở dữ liệu của bạn hỗ trợ các chế độ xem Information_SCHema, hãy lấy kết quả của truy vấn sau và thực hiện chúng.
SELECT 'TRUNCATE TABLE ' + TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
Hãy thử điều này cho MySQL:
SELECT Concat('TRUNCATE TABLE ', TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES
Thêm dấu chấm phẩy vào Concat giúp sử dụng dễ dàng hơn, ví dụ như từ trong bàn làm việc của mysql.
SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES
Tôi thấy điều này để thả tất cả các bảng trong cơ sở dữ liệu:
mysqldump -uUSERNAME -pPASSWORD --add-drop-table --no-data DATABASENAME | grep ^DROP | mysql -uUSERNAME -pPASSWORD DATABASENAME
Sử dụng đầy đủ nếu bạn bị giới hạn bởi giải pháp lưu trữ (không thể bỏ toàn bộ cơ sở dữ liệu).
Tôi đã sửa đổi nó để cắt bớt các bảng. Không có "--add-truncate-table" cho mysqldump, vì vậy tôi đã làm:
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
làm việc cho tôi --edit, sửa lỗi chính tả trong lệnh cuối cùng
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
thành:AND table_schema = DATABASE();
Tôi thấy đơn giản nhất là chỉ cần làm một cái gì đó giống như mã bên dưới, chỉ cần thay thế tên bảng bằng tên của bạn. điều quan trọng là đảm bảo dòng cuối cùng luôn luôn là FOR 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;
Điều này sẽ in lệnh để cắt tất cả các bảng:
SELECT GROUP_CONCAT(Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME) SEPARATOR ';') FROM INFORMATION_SCHEMA.TABLES where table_schema in ('my_db');
Khi việc cắt dữ liệu được thực hiện, hãy tạo lại các ràng buộc khóa ngoại tương tự trên cùng một bảng. Xem bên dưới một tập lệnh sẽ tạo tập lệnh để thực hiện các hoạt động trên.
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';
Bây giờ, hãy chạy tập lệnh Db Truncate.sql được tạo
Những lợi ích. 1) Lấy lại không gian đĩa 2) Không cần thiết phải thả và tạo lại DB / Schema với cùng cấu trúc
Hạn chế. 1) Ràng buộc FK phải là tên trong bảng có tên chứa 'FK' trong tên ràng buộc.
nếu sử dụng máy chủ sql 2005, có một thủ tục được lưu trữ ẩn cho phép bạn thực thi một lệnh hoặc một tập lệnh đối với tất cả các bảng bên trong cơ sở dữ liệu. Đây là cách bạn sẽ gọi TRUNCATE TABLE
với thủ tục được lưu trữ này:
EXEC [sp_MSforeachtable] @command1="TRUNCATE TABLE ?"
Đây là một bài viết tốt mà chi tiết hơn nữa.
Tuy nhiên, đối với MySql, bạn có thể sử dụng mysqldump và chỉ định --add-drop-tables
và --no-data
các tùy chọn để loại bỏ và tạo tất cả các bảng bỏ qua dữ liệu. như thế này:
mysqldump -u[USERNAME] -p[PASSWORD] --add-drop-table --no-data [DATABASE]
Sử dụng cái này và tạo truy vấn
SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES where table_schema in (db1,db2)
INTO OUTFILE '/path/to/file.sql';
Bây giờ sử dụng để sử dụng truy vấn này
mysql -u username -p </path/to/file.sql
nếu bạn gặp lỗi như thế này
ERROR 1701 (42000) at line 3: Cannot truncate a table referenced in a foreign key constraint
cách dễ nhất để đi qua là ở đầu tệp của bạn thêm dòng này
SET FOREIGN_KEY_CHECKS=0;
trong đó nói rằng chúng tôi không muốn kiểm tra các ràng buộc khóa ngoại trong khi duyệt qua tệp này.
Nó sẽ cắt tất cả các bảng trong cơ sở dữ liệu db1 và bd2.
Không. Không có lệnh nào để cắt tất cả các bảng mysql cùng một lúc. Bạn sẽ phải tạo một tập lệnh nhỏ để cắt từng bảng một.
ref: http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html
Đây là biến thể của tôi để có 'một tuyên bố cắt ngắn' tất cả '.
Đầu tiên, tôi đang sử dụng một cơ sở dữ liệu riêng có tên 'produc' cho các thủ tục được lưu trữ của người trợ giúp. Mã của thủ tục được lưu trữ của tôi để cắt bớt tất cả các bảng là:
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 ;
Khi bạn có quy trình được lưu trữ này trong cơ sở dữ liệu của bạn, bạn có thể gọi nó như
call util.trunctables('nameofdatabase');
mà bây giờ chính xác là một tuyên bố :-)
ở đây cho tôi biết ở đây
SELECT Concat('TRUNCATE TABLE ',table_schema,'.',TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES where table_schema in ('databasename1','databasename2');
Nếu không thể xóa hoặc cập nhật hàng cha mẹ: một ràng buộc khóa ngoại không thành công
Điều đó xảy ra nếu có các bảng có tham chiếu khóa ngoài tới bảng mà bạn đang cố gắng thả / cắt.
Trước khi cắt bớt bảng Tất cả những gì bạn cần làm là:
SET FOREIGN_KEY_CHECKS=0;
Cắt bớt các bảng của bạn và thay đổi nó trở lại
SET FOREIGN_KEY_CHECKS=1;
sử dụng mã php này
$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']);
}
?>
kiểm tra chi tiết ở đây liên kết
Đây là một thủ tục nên cắt bớt tất cả các bảng trong cơ sở dữ liệu cục bộ.
Hãy cho tôi biết nếu nó không hoạt động và tôi sẽ xóa câu trả lời này.
Chưa được kiểm tra
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;
Tôi thấy rằng BẢNG TRUNCATE .. gặp rắc rối với các ràng buộc khóa ngoại, ngay cả sau khi NOCHECK CONSTRAINT ALL, vì vậy tôi sử dụng câu lệnh XÓA TỪ thay thế. Điều này không có nghĩa là các hạt giống nhận dạng không được đặt lại, bạn luôn có thể thêm CHECKIDENT để đạt được điều này.
Tôi sử dụng mã dưới đây để in ra cửa sổ thông báo sql để cắt bớt tất cả các bảng trong cơ sở dữ liệu, trước khi chạy nó. Nó chỉ làm cho một chút khó khăn hơn để phạm sai lầm.
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'''
Tôi không chắc nhưng tôi nghĩ có một lệnh sử dụng mà bạn có thể sao chép lược đồ cơ sở dữ liệu vào cơ sở dữ liệu mới, khi bạn đã hoàn thành việc này, bạn có thể xóa cơ sở dữ liệu cũ và sau đó, bạn có thể sao chép lại lược đồ cơ sở dữ liệu sang tên cũ.
Tôi biết đây không chính xác là một lệnh, nhưng kết quả mong muốn có thể đạt được từ bên trong phpMyAdmin bằng cách làm theo các bước sau:
Ý tưởng là nhanh chóng lấy tất cả các bảng từ cơ sở dữ liệu (bạn thực hiện trong 5 giây và 2 lần nhấp) nhưng trước tiên hãy vô hiệu hóa kiểm tra khóa ngoại. Không CLI và không bỏ cơ sở dữ liệu và thêm nó một lần nữa.
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
-
David,
Cảm ơn bạn đã dành thời gian để định dạng mã, nhưng đây là cách nó được áp dụng.
-Kurt
Trên hộp UNIX hoặc Linux:
Hãy chắc chắn rằng bạn đang ở trong một vỏ bash. Các lệnh này sẽ được chạy, từ dòng lệnh như sau.
Ghi chú:
Tôi lưu trữ thông tin đăng nhập của mình trong tệp ~ / .my.cnf của mình, vì vậy tôi không cần cung cấp chúng trên dòng lệnh.
Ghi chú:
cpm là tên cơ sở dữ liệu
Tôi chỉ hiển thị một mẫu nhỏ của kết quả, từ mỗi lệnh.
Tìm các ràng buộc khóa ngoại của bạn:
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"
Liệt kê các bảng và số hàng:
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
Cắt bớt các bảng của bạn:
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
Xác minh rằng nó hoạt động:
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
Trên hộp Windows:
GHI CHÚ:
cpm là tên cơ sở dữ liệu
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
Truy vấn MySQL sau đây sẽ tự tạo một truy vấn duy nhất sẽ cắt tất cả các bảng trong cơ sở dữ liệu đã cho. Nó bỏ qua các phím NGOẠI TỆ:
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
Sol 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;
Ngày 2)
- Export only structure of a db
- drop the database
- import the .sql of structure
-- biên tập ----
earlier in solution 1, i had mentioned concat() instead of group_concat() which would have not returned the desired result
Một ý tưởng có thể là chỉ cần thả và tạo lại các bảng?
BIÊN TẬP:
@Jonathan Leffler: Đúng
Đề xuất khác (hoặc trường hợp bạn không cần cắt bớt TẤT CẢ các bảng):
Tại sao không chỉ tạo một thủ tục lưu trữ cơ bản để cắt bớt các bảng cụ thể
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();
?>
Đây là đoạn mã mà tôi sử dụng để xóa bảng. Chỉ cần thay đổi thông tin $ Conn và TABLE_NAME.