Respostas:
Use INSERT ... SELECT
:
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1
Onde c1, c2, ...
estão todas as colunas, exceto id
. Se você deseja inserir explicitamente com um id
de 2, inclua-o na lista de colunas INSERT e em SELECT:
insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1
Você terá que cuidar de uma possível duplicata id
de 2 no segundo caso, é claro.
Na IMO, o melhor parece usar instruções sql apenas para copiar essa linha, enquanto ao mesmo tempo faz referência apenas às colunas que você deve e deseja alterar.
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;
Consulte também av8n.com - Como clonar um registro SQL
Benefícios:
your_table
em uma operação atômica.Error Code: 1113. A table must have at least 1 column
.
SET id=NULL
pode causar um erro Column 'id' cannot be null
. Deve ser substituído porUPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
Diga que a mesa está user(id, user_name, user_email)
.
Você pode usar esta consulta:
INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
Result: near "SELECT": syntax error
Isso ajudou e suporta colunas 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;
Para uma solução rápida e limpa que não exige que você nomeie colunas, você pode usar uma instrução preparada conforme descrito aqui: https://stackoverflow.com/a/23964285/292677
Se você precisar de uma solução complexa para poder fazer isso com frequência, use este procedimento:
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
Você pode executá-lo com:
CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');
Exemplos
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
AVISO LEGAL: Esta solução é apenas para alguém que duplicará repetidamente linhas em muitas tabelas, frequentemente. Pode ser perigoso nas mãos de um usuário não autorizado.
Você também pode passar '0' como o valor para o incremento automático da coluna; o valor correto será usado quando o registro for criado. Isso é muito mais fácil do que tabelas temporárias.
Fonte: Copiando linhas no MySQL (veja o segundo comentário, por TRiG, para a primeira solução, por Lore)
Muitas ótimas respostas aqui. Abaixo está um exemplo do procedimento armazenado que escrevi para realizar esta tarefa para um aplicativo da Web que estou desenvolvendo:
-- 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;
Se você pode usar o MySQL Workbench, você pode fazer isso clicando com o botão direito do mouse na linha e selecionando 'Copiar linha' e, em seguida, clicando com o botão direito do mouse na linha vazia e selecionando 'Colar linha' e, em seguida, alterando o ID e, em seguida, clicando em 'Aplicar'.
Copie a linha:
Cole a linha copiada na linha em branco:
Mude o ID:
Aplique:
Eu estava procurando o mesmo recurso, mas não uso o MySQL. Eu queria copiar TODOS os campos, exceto, é claro, a chave primária (id). Esta foi uma consulta única, que não deve ser usada em nenhum script ou código.
Encontrei o caminho com PL / SQL, mas tenho certeza de que qualquer outro IDE SQL faria. Eu fiz um básico
SELECT *
FROM mytable
WHERE id=42;
Em seguida, exporte-o para um arquivo SQL onde eu possa encontrar o
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (1, 2, 3, ..., 42);
Eu apenas editei e usei:
INSERT INTO table (col1, col2, col3, ... , col42)
VALUES (mysequence.nextval, 2, 3, ..., 42);
Costumo usar uma variação do que mu é muito curto postado:
INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;
Contanto que as tabelas tenham campos idênticos (exceto o incremento automático na tabela de log), isso funcionará bem.
Como uso procedimentos armazenados sempre que possível (para facilitar a vida de outros programadores que não estão muito familiarizados com bancos de dados), isso resolve o problema de ter que voltar e atualizar procedimentos toda vez que você adiciona um novo campo a uma tabela.
Também garante que, se você adicionar novos campos a uma tabela, eles começarão a aparecer na tabela de log imediatamente sem precisar atualizar suas consultas ao banco de dados (a menos que você tenha algumas que definam um campo explicitamente)
Aviso: Você deseja adicionar novos campos às duas tabelas ao mesmo tempo, para que a ordem dos campos permaneça a mesma ... caso contrário, você começará a receber bugs estranhos. Se você é o único que escreve interfaces de banco de dados E você é muito cuidadoso, isso funciona muito bem. Caso contrário, continue nomeando todos os seus campos.
Nota: Pensando bem, a menos que você esteja trabalhando em um projeto solo, você tem certeza de que não haverá outros trabalhando nele para listar todos os nomes de campos explicitamente e atualizar suas instruções de log conforme o esquema muda. Esse atalho provavelmente não vale a dor de cabeça a longo prazo que pode causar ... especialmente em um sistema de produção.
INSERIR EM `dbMyDataBase`.`tblMyTable` ( `IdAutoincrement`, `Coluna2`, `Coluna3`, `Coluna4` ) SELECT NULO, `Coluna2`, `Coluna3`, 'CustomValue' AS Column4 FROM `dbMyDataBase` .tblMyTable` WHERE `tblMyTable`.`Column2` = 'UniqueValueOfTheKey' ; / * mySQL 5.6 * /