Odpowiedzi:
Użyj INSERT ... SELECT
:
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1
gdzie c1, c2, ...
są wszystkie kolumny oprócz id
. Jeśli chcesz jawnie wstawić z id
2, umieść to na liście kolumn WSTAW i wybierz:
insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1
Oczywiście id
w drugim przypadku musisz zająć się możliwym duplikatem 2.
IMO, najlepiej wydaje się używać instrukcji sql tylko do kopiowania tego wiersza, a jednocześnie tylko do odwoływania się do kolumn, które musisz i chcesz zmienić.
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;
Zobacz także av8n.com - jak sklonować rekord SQL
Korzyści:
your_table
w jednej operacji atomowej.Error Code: 1113. A table must have at least 1 column
.
SET id=NULL
może powodować błąd Column 'id' cannot be null
. Powinien zostać zastąpiony przezUPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
Powiedz, że stół jest user(id, user_name, user_email)
.
Możesz użyć tego zapytania:
INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
Result: near "SELECT": syntax error
Pomogło to i obsługuje kolumny 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;
Aby uzyskać szybkie, czyste rozwiązanie, które nie wymaga nazywania kolumn, możesz użyć przygotowanej instrukcji, jak opisano tutaj: https://stackoverflow.com/a/23964285/292677
Jeśli potrzebujesz złożonego rozwiązania, które możesz wykonywać często, możesz skorzystać z tej procedury:
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
Możesz go uruchomić za pomocą:
CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');
Przykłady
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
ZASTRZEŻENIE: To rozwiązanie jest przeznaczone tylko dla kogoś, kto często będzie powtarzał wiersze w wielu tabelach. Może być niebezpieczne w rękach nieuczciwego użytkownika.
Możesz również podać „0” jako wartość kolumny do automatycznego przyrostu, przy tworzeniu rekordu zostanie użyta poprawna wartość. Jest to o wiele łatwiejsze niż tabele tymczasowe.
Źródło: Kopiowanie wierszy w MySQL (patrz drugi komentarz TRiG do pierwszego rozwiązania autorstwa Lore)
Wiele świetnych odpowiedzi tutaj. Poniżej znajduje się przykład procedury składowanej, którą napisałem, aby wykonać to zadanie dla opracowywanej przeze mnie aplikacji sieci Web:
-- 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;
Jeśli możesz używać MySQL Workbench, możesz to zrobić, klikając prawym przyciskiem myszy wiersz i wybierając „Kopiuj wiersz”, a następnie klikając prawym przyciskiem myszy pusty wiersz i wybierając „Wklej wiersz”, a następnie zmieniając identyfikator, a następnie klikając „Zastosuj”.
Skopiuj wiersz:
Wklej skopiowany wiersz do pustego wiersza:
Zmień identyfikator:
Zastosować:
Szukałem tej samej funkcji, ale nie używam MySQL. Chciałem skopiować WSZYSTKIE pola oprócz oczywiście klucza podstawowego (id). To było zapytanie jednorazowe, którego nie można używać w żadnym skrypcie ani kodzie.
Znalazłem się w PL / SQL, ale jestem pewien, że zrobiłoby to każde inne IDE SQL. Zrobiłem podstawowy
SELECT *
FROM mytable
WHERE id=42;
Następnie wyeksportuj go do pliku SQL, w którym mógłbym znaleźć
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (1, 2, 3, ..., 42);
Właśnie go edytowałem i użyłem:
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (mysequence.nextval, 2, 3, ..., 42);
Zwykle używam odmiany tego, co mu jest zbyt krótkie:
INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;
Tak długo, jak tabele mają identyczne pola (z wyjątkiem automatycznego przyrostu w tabeli dziennika), działa to dobrze.
Ponieważ w miarę możliwości korzystam z procedur przechowywanych (aby ułatwić życie innym programistom, którzy nie są zbyt obeznani z bazami danych), rozwiązuje to problem konieczności cofania się i aktualizowania procedur za każdym razem, gdy dodajesz nowe pole do tabeli.
Zapewnia również, że jeśli dodasz nowe pola do tabeli, natychmiast zaczną pojawiać się w tabeli dziennika bez konieczności aktualizowania zapytań do bazy danych (chyba że masz takie, które wyraźnie ustawiają pole)
Ostrzeżenie: Pamiętaj, aby dodać nowe pola do obu tabel jednocześnie, aby kolejność pól pozostała taka sama ... w przeciwnym razie zaczniesz otrzymywać dziwne błędy. Jeśli jesteś jedynym, który pisze interfejsy bazy danych ORAZ jesteś bardzo ostrożny, to działa dobrze. W przeciwnym razie trzymaj się nazewnictwa wszystkich swoich pól.
Uwaga: Z drugiej strony, chyba że pracujesz nad projektem solowym, masz pewność, że inni nie będą pracować nad tym, aby jawnie wypisywać wszystkie nazwy pól i aktualizować instrukcje dziennika w miarę zmiany schematu. Ten skrót prawdopodobnie nie jest wart długoterminowego bólu głowy, który może powodować ... zwłaszcza w systemie produkcyjnym.
WSTAW DO `dbMyDataBase` .tblMyTable` ( „IdAutoincrement”, „Kolumna2”, „Kolumna3”, `Kolumna4` ) WYBIERZ ZERO, „Kolumna2”, „Kolumna3”, Kolumna „CustomValue” AS FROM `dbMyDataBase` .tblMyTable` GDZIE `tblMyTable``Column2` = 'UniqueValueOfTheKey' ; / * mySQL 5.6 * /