Câu trả lời:
Sử dụng INSERT ... SELECT
:
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1
nơi c1, c2, ...
là tất cả các cột trừ id
. Nếu bạn muốn chèn một cách rõ ràng bằng một id
trong 2 thì hãy đưa nó vào danh sách cột INSERT và CHỌN của bạn:
insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1
Tất nhiên, bạn sẽ phải chăm sóc một bản sao có thể có id
của 2 trong trường hợp thứ hai.
IMO, tốt nhất dường như chỉ sử dụng các câu lệnh sql để sao chép hàng đó, đồng thời chỉ tham chiếu các cột bạn phải và muốn thay đổi.
CREATE TEMPORARY TABLE temp_table ENGINE=MEMORY
SELECT * FROM your_table WHERE id=1;
UPDATE temp_table SET id=NULL; /* Update other values at will. */
INSERT INTO your_table SELECT * FROM temp_table;
DROP TABLE temp_table;
Xem thêm av8n.com - Cách sao chép bản ghi SQL
Những lợi ích:
your_table
trong một hoạt động nguyên tử.Error Code: 1113. A table must have at least 1 column
.
SET id=NULL
có thể gây ra lỗi Column 'id' cannot be null
. Nên được thay thế bằngUPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
Nói cái bàn là thế user(id, user_name, user_email)
.
Bạn có thể sử dụng truy vấn này:
INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
Result: near "SELECT": syntax error
Điều này đã giúp và nó hỗ trợ một cột BLOB / TEXT.
CREATE TEMPORARY TABLE temp_table
AS
SELECT * FROM source_table WHERE id=2;
UPDATE temp_table SET id=NULL WHERE id=2;
INSERT INTO source_table SELECT * FROM temp_table;
DROP TEMPORARY TABLE temp_table;
USE source_table;
Để có giải pháp nhanh chóng, gọn gàng không yêu cầu bạn đặt tên cột, bạn có thể sử dụng câu lệnh được chuẩn bị như mô tả tại đây: https://stackoverflow.com/a/23944285/292677
Nếu bạn cần một giải pháp phức tạp để bạn có thể làm điều này thường xuyên, bạn có thể sử dụng quy trình này:
DELIMITER $$
CREATE PROCEDURE `duplicateRows`(_schemaName text, _tableName text, _whereClause text, _omitColumns text)
SQL SECURITY INVOKER
BEGIN
SELECT IF(TRIM(_omitColumns) <> '', CONCAT('id', ',', TRIM(_omitColumns)), 'id') INTO @omitColumns;
SELECT GROUP_CONCAT(COLUMN_NAME) FROM information_schema.columns
WHERE table_schema = _schemaName AND table_name = _tableName AND FIND_IN_SET(COLUMN_NAME,@omitColumns) = 0 ORDER BY ORDINAL_POSITION INTO @columns;
SET @sql = CONCAT('INSERT INTO ', _tableName, '(', @columns, ')',
'SELECT ', @columns,
' FROM ', _schemaName, '.', _tableName, ' ', _whereClause);
PREPARE stmt1 FROM @sql;
EXECUTE stmt1;
END
Bạn có thể chạy nó với:
CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');
Ví dụ
duplicateRows('acl', 'users', 'WHERE id = 200'); -- will duplicate the row for the user with id 200
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts'); -- same as above but will not copy the created_ts column value
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts,updated_ts'); -- same as above but also omits the updated_ts column
duplicateRows('acl', 'users'); -- will duplicate all records in the table
TUYÊN BỐ TỪ CHỐI: Giải pháp này chỉ dành cho người thường xuyên lặp lại các hàng trong nhiều bảng. Nó có thể nguy hiểm trong tay của một người dùng lừa đảo.
Bạn cũng có thể chuyển vào '0' làm giá trị cho cột để tự động tăng, giá trị đúng sẽ được sử dụng khi bản ghi được tạo. Điều này là rất dễ dàng hơn nhiều so với các bảng tạm thời.
Nguồn: Sao chép các hàng trong MySQL (xem bình luận thứ hai, của TRiG, cho giải pháp đầu tiên, bởi Lore)
Rất nhiều câu trả lời tuyệt vời ở đây. Dưới đây là một mẫu về quy trình được lưu trữ mà tôi đã viết để hoàn thành nhiệm vụ này cho Ứng dụng web mà tôi đang phát triển:
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Create Temporary Table
SELECT * INTO #tempTable FROM <YourTable> WHERE Id = Id
--To trigger the auto increment
UPDATE #tempTable SET Id = NULL
--Update new data row in #tempTable here!
--Insert duplicate row with modified data back into your table
INSERT INTO <YourTable> SELECT * FROM #tempTable
-- Drop Temporary Table
DROP TABLE #tempTable
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
Nếu bạn có thể sử dụng MySQL Workbench, bạn có thể thực hiện việc này bằng cách nhấp chuột phải vào hàng và chọn 'Sao chép hàng', sau đó bấm chuột phải vào hàng trống và chọn 'Dán hàng', sau đó thay đổi ID, sau đó thay đổi ID nhấp vào 'Áp dụng'.
Sao chép hàng:
Dán hàng đã sao chép vào hàng trống:
Thay đổi ID:
Ứng dụng:
Tôi đã tìm kiếm tính năng tương tự nhưng tôi không sử dụng MySQL. Tôi muốn sao chép TẤT CẢ các trường trừ khóa chính (id). Đây là truy vấn một lần, không được sử dụng trong bất kỳ tập lệnh hoặc mã nào.
Tôi đã tìm thấy cách của mình với PL / SQL nhưng tôi chắc chắn rằng bất kỳ IDE SQL nào khác sẽ làm được. Tôi đã làm một cơ bản
SELECT *
FROM mytable
WHERE id=42;
Sau đó xuất nó thành tệp SQL nơi tôi có thể tìm thấy
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (1, 2, 3, ..., 42);
Tôi chỉ chỉnh sửa nó và sử dụng nó:
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (mysequence.nextval, 2, 3, ..., 42);
Tôi có xu hướng sử dụng một biến thể của những gì mu quá ngắn được đăng:
INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;
Miễn là các bảng có các trường giống hệt nhau (ngoại trừ tăng tự động trên bảng nhật ký), thì bảng này hoạt động độc đáo.
Vì tôi sử dụng các thủ tục được lưu trữ bất cứ khi nào có thể (để làm cho cuộc sống dễ dàng hơn đối với các lập trình viên khác, những người không quá quen thuộc với cơ sở dữ liệu), điều này giải quyết vấn đề phải quay lại và cập nhật các thủ tục mỗi khi bạn thêm trường mới vào bảng.
Nó cũng đảm bảo rằng nếu bạn thêm các trường mới vào một bảng, chúng sẽ bắt đầu xuất hiện trong bảng nhật ký ngay lập tức mà không phải cập nhật các truy vấn cơ sở dữ liệu của bạn (trừ khi tất nhiên bạn có một số trường đặt trường rõ ràng)
Cảnh báo: Bạn sẽ muốn đảm bảo thêm bất kỳ trường mới nào vào cả hai bảng cùng một lúc để thứ tự trường giữ nguyên ... nếu không bạn sẽ bắt đầu gặp lỗi lạ. Nếu bạn là người duy nhất viết giao diện cơ sở dữ liệu VÀ bạn rất cẩn thận thì điều này sẽ hoạt động tốt. Nếu không, hãy đặt tên cho tất cả các lĩnh vực của bạn.
Lưu ý: Về ý nghĩ thứ hai, trừ khi bạn đang làm việc trong một dự án solo mà bạn chắc chắn sẽ không có người khác làm việc trên đó để liệt kê rõ ràng tất cả các tên trường và cập nhật báo cáo nhật ký của bạn khi thay đổi lược đồ của bạn. Phím tắt này có lẽ không đáng để đau đầu lâu dài mà nó có thể gây ra ... đặc biệt là trên một hệ thống sản xuất.
XÁC NHẬN VÀO `dbMyDataBase`.`tblMyTable` ( `IdAutoincrement`, `Cột2`, `Cột3`, `Cột4` ) LỰA CHỌN VÔ GIÁ TRỊ, `Cột2`, `Cột3`, 'CustomValue' AS Cột4 TỪ `dbMyDataBase`.`tblMyTable` Ở đâu `tblMyTable`.`Column2` = 'UniqueValueOfTheKey' ; / * myQuery 5.6 * /