No MySQL, posso copiar uma linha para inserir na mesma tabela?

162
insert into table select * from table where primarykey=1

Eu só quero copiar uma linha para inserir na mesma tabela (ou seja, desejo duplicar uma linha existente na tabela), mas quero fazer isso sem precisar listar todas as colunas após o "select", porque esta tabela possui muitas colunas.

Mas quando faço isso, recebo o erro:

Entrada duplicada 'xxx' para a chave 1

Eu posso lidar com isso criando outra tabela com as mesmas colunas que um contêiner temporário para o registro que quero copiar:

create table oldtable_temp like oldtable;
insert into oldtable_temp select * from oldtable where key=1;
update oldtable_tem set key=2;
insert into oldtable select * from oldtable where key=2;

Existe uma maneira mais simples de resolver isso?

lina
fonte
Eu apenas tenho um comentário sobre os valores codificados da chave. Eu faria algo assim, max(oldtable.id) + oldtable_temp.keypara garantir que os IDs aumentem e sejam únicos.
cara Mograbi
Possível duplicata de registros duplicados /
Organic Advocate
@OrganicAdvocate isso tem mais respostas e mais vistas do que essa pergunta
de Drew

Respostas:

189

Usei a técnica de Leonard Challis com algumas mudanças:

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;

Como uma tabela temporária, nunca deve haver mais de um registro; portanto, você não precisa se preocupar com a chave primária. Configurá-lo como nulo permite que o MySQL escolha o valor em si, então não há risco de criar uma duplicata.

Se você quiser ter certeza de que está inserindo apenas uma linha, adicione LIMIT 1 ao final da linha INSERT INTO.

Observe que também anexei o valor da chave primária (1 neste caso) ao meu nome de tabela temporário.

Grim ...
fonte
3
Esta solução está correta (em contraste com outras que obtiveram votos), pois permite que o MySQL escolha o valor da chave primária.
Jan Hettich
1
Embora não vai funcionar exatamente como é devido a nomes de tabelas temporárias inconsistentes ( tmptable_1vs. tmptable)
Kieran Tully
9
Como uma chave primária pode ser nula?
Imran Shafqat
5
Se for nulo, ele recebe automaticamente o próximo número de AI quando é inserido.
Grim ...
2
IMRAN - você pode perguntar. Eu pensei que talvez o campo de identificação da tabela temporária não tenha sido transformado automaticamente em PK (eu tenho certeza que o SQL Server não faz isso nessas circunstâncias), mas é. Eu precisava fazer ALTER TABLE tmptable_1 MODIFY primarykeyINT NULL; depois da primeira linha para fazer o trabalho solução
DJDave
61

Atualização 07/07/2014 - A resposta com base em minha resposta, de Grim ... , é uma solução melhor, pois melhora minha solução abaixo, então sugiro usá-la.

Você pode fazer isso sem listar todas as colunas com a seguinte sintaxe:

CREATE TEMPORARY TABLE tmptable SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable SET primarykey = 2 WHERE primarykey = 1;
INSERT INTO table SELECT * FROM tmptable WHERE primarykey = 2;

Você pode alterar a chave primária de outra maneira.

LeonardChallis
fonte
16
Esta é basicamente a mesma solução que o OP já havia fornecido para o seu próprio problema, embora com tabelas temporárias reais e um padrão de criação um pouco mais limpo. Eu acho que o OP pediu uma abordagem melhor para o que eles já estavam usando, não uma limpeza de sua sintaxe existente. Realmente não entendo todos os votos positivos para isso.
Sepster
Obrigado. Sua indo bem com função dinâmica
Sonal Khunt
É necessário excluir o tmptable após a conclusão desse processo?
SSH No
"Por padrão, todas as tabelas temporárias são excluídas pelo MySQL quando sua conexão com o banco de dados é encerrada. Ainda assim, você deseja excluí-las entre elas, emitindo o comando DROP TABLE." Mais aqui
LeonardChallis
Como você criou o tmptable, você não precisa adicionar a WHERE primarykey = 2instrução para a última linha também. (Ou seja, apenas INSERT INTO table SELECT * FROM tmptable.) #
1155 Marcus
42

Estou assumindo que você deseja que o novo disco tenha um novo primarykey? Se primarykeyfor AUTO_INCREMENT, faça o seguinte:

INSERT INTO table (col1, col2, col3, ...)
SELECT col1, col2, col3, ... FROM table
  WHERE primarykey = 1

... onde col1, col2, col3, ...estão todas as colunas da tabela, exceto primarykey .

Se não é uma AUTO_INCREMENTcoluna e você deseja escolher o novo valor primarykey, é semelhante:

INSERT INTO table (primarykey, col2, col3, ...)
SELECT 567, col2, col3, ... FROM table
  WHERE primarykey = 1

... para onde 567está o novo valor primarykey.

Jordan Running
fonte
41
Como é que isso é votado 7 vezes quando ignora a pergunta? ... mas eu não quero listar todas as colunas após a "escolha", porque esta tabela tem muitas colunas ...
LeonardChallis
7
-1, pois é exatamente isso que o OP deseja evitar. Leia a pergunta ou, pelo menos, ofereça uma resposta como "esse é o único caminho possível".
devios1
5
Porque às vezes a pergunta em si está errada. :) Duplicar linhas sem alterar o conteúdo aumenta a redundância. A alteração da estrutura do banco de dados para minimizar a redundância deve ser recomendada, se possível.
Torben
5
Só porque não está certo nas práticas normais, não erra. Há muitas vezes em que as práticas recomendadas padrão não se aplicam. Exemplo: o banco de dados representa documentos e um usuário precisa preservar uma cópia de um documento antes de fazer alterações.
ima747
6
Porque você pode pousar em esta página não querendo exatamente o mesmo que o OP
jx12345
13

Você quase a teve na sua primeira consulta, apenas especificando as colunas; dessa forma, você pode excluir sua chave primária na inserção, o que aumentará o incremento automático que você provavelmente terá na tabela para criar automaticamente uma nova chave primária para a coluna. entrada.

Por exemplo, altere isso:

insert into table select * from table where primarykey=1

Para isso:

INSERT INTO table (col1, col2, col3) 
SELECT col1, col2, col3 
FROM table 
WHERE primarykey = 1

Apenas não inclua a coluna primarykey na lista de colunas para as partes INSERT ou SELECT da consulta.

Braeden Black
fonte
1
existe uma maneira de puxar a maioria das colunas através da instrução select, mas atualize uma delas manualmente no comando insert? como insert into table ("val1", col2, col3) select col2, col3 from table where primarykey = 1ou algo semelhante?
anon58192932
1
Encontrei! Copie os valores de uma linha, mas adicione um dos seus próprios valores na instrução insert: stackoverflow.com/questions/23971078/…
anon58192932:
1
Desculpe, acabei de ser notificado de suas perguntas, feliz por encontrá-lo, esse é realmente o caminho.
Braeden Black
9

Você também pode tentar despejar a tabela, localizando o comando insert e editando-o:

mysqldump -umyuser -p mydatabase --skip-extended-insert mytable > outfile.sql

O --skip-extended-insertfornece um comando de inserção por linha. Você pode encontrar a linha no seu editor de texto favorito, extrair o comando e alterar a chave primária para "padrão".

donutingsuccessfully
fonte
2
+1 de mim, pois essa é uma boa abordagem "fora da caixa" que pode realmente ser útil fora do tempo de execução, em algumas circunstâncias. Mas, principalmente, é a primeira resposta que realmente aborda a questão do OP e não apenas ajusta sintaticamente a solução já fornecida pelo OP.
Sepster
6

Este procedimento supõe que:

  • você não tem _duplicate_temp_table
  • sua chave primária é int
  • você tem acesso para criar tabela

É claro que isso não é perfeito, mas em alguns casos (provavelmente na maioria) ele funcionará.

DELIMITER $$
CREATE PROCEDURE DUPLICATE_ROW(copytable VARCHAR(255), primarykey VARCHAR(255), copyid INT, out newid INT)
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @error=1;
        SET @temptable = '_duplicate_temp_table';
        SET @sql_text = CONCAT('CREATE TABLE ', @temptable, ' LIKE ', copytable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', @temptable, ' SELECT * FROM ', copytable, ' where ', primarykey,'=', copyid);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('SELECT max(', primarykey, ')+1 FROM ', copytable, ' INTO @newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('UPDATE ', @temptable, ' SET ', primarykey, '=@newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', copytable, ' SELECT * FROM ', @temptable, '');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('DROP TABLE ', @temptable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SELECT @newid INTO newid;
END $$
DELIMITER ;

CALL DUPLICATE_ROW('table', 'primarykey', 1, @duplicate_id);
SELECT @duplicate_id;
Piotr Kaczmarek
fonte
1
O +1 não confirmou isso, worksmas a abordagem é sólida e tem valor, pois é única aqui e realmente aborda a questão do OP.
Sepster
5

Isso pode ser alcançado com alguma criatividade:

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

Isso fará com que a nova linha obtenha um ID incrementado automaticamente em vez do ID da linha selecionada.

curmil
fonte
Esta deve ser a resposta aceita!
Felipe Desiderati
5

Se o campo de chave primária da sua tabela for um campo de incremento automático, você poderá usar a consulta com colunas. Por exemplo, sua tabela denominada test_tblpossui 3 campos como id, name, age. idé um campo de chave primária e incremento automático, para que você possa usar a seguinte consulta para duplicar a linha:

INSERT INTO `test_tbl` (`name`,`age`) SELECT `name`,`age` FROM `test_tbl`;

Essa consulta resulta na duplicação de cada linha.


Se o campo de chave primária da sua tabela não for um campo de incremento automático, você poderá usar o seguinte método:

INSERT INTO `test_tbl` (`id`,`name`,`age`)
  SELECT 20,`name`,`age` FROM `test_tbl` WHERE id = 19;

O resultado desta consulta é uma linha duplicada de id=19inserida como id=20.

user2595171
fonte
Essa é a melhor resposta que existe, o caso é bastante simples: INSERT INTO tableName( fieldName1, fieldName2, fieldName3) Selecione fieldName1, fieldName2, fieldName3DE tableNameONDE 1 (para copiar todos eles de uma vez)
jakubplus
Destacado - essa resposta é sucinta e no espírito de "Copiar" uma linha.
user37309
4

clonar linha com campos de atualização e valor de incremento automático

CREATE TEMPORARY TABLE `temp` SELECT * FROM `testing` WHERE id = 14;

UPDATE `temp` SET id = (SELECT id FROM testing ORDER by id DESC LIMIT 1
 )+1, user_id = 252 ,policy_no = "mysdddd12" where id = 14;

INSERT INTO `testing` SELECT * FROM `temp`;

DROP TEMPORARY TABLE IF EXISTS `temp`;
Shrinivas Mahindrakar
fonte
@Torben Por favor, verifique o visto à esquerda da pergunta (marque-o como aceito) para que todos saibam que funcionou para você.
HosseyNJF
3

Alguns dos itens a seguir foram recolhidos deste site. Isto é o que eu fiz para duplicar um registro em uma tabela com qualquer número de campos:

Isso também pressupõe que você tenha um campo de AI no início da tabela

function duplicateRow( $id = 1 ){
dbLink();//my db connection
$qColumnNames = mysql_query("SHOW COLUMNS FROM table") or die("mysql error");
$numColumns = mysql_num_rows($qColumnNames);

for ($x = 0;$x < $numColumns;$x++){
$colname[] = mysql_fetch_row($qColumnNames);
}

$sql = "SELECT * FROM table WHERE tableId = '$id'";
$row = mysql_fetch_row(mysql_query($sql));
$sql = "INSERT INTO table SET ";
for($i=1;$i<count($colname)-4;$i++){//i set to 1 to preclude the id field
//we set count($colname)-4 to avoid the last 4 fields (good for our implementation)
$sql .= "`".$colname[$i][0]."`  =  '".$row[$i]. "', ";
}
$sql .= " CreateTime = NOW()";// we need the new record to have a new timestamp
mysql_query($sql);
$sql = "SELECT MAX(tableId) FROM table";
$res = mysql_query($sql);
$row = mysql_fetch_row($res);
return $row[0];//gives the new ID from auto incrementing
}
richardwhitney
fonte
2

Eu posso estar atrasado nisso, mas tenho uma solução semelhante que funcionou para mim.

 INSERT INTO `orders` SELECT MAX(`order_id`)+1,`container_id`, `order_date`, `receive_date`, `timestamp` FROM `orders` WHERE `order_id` = 1

Dessa forma, não preciso criar uma tabela temporária e etc. Como a linha é copiada na mesma tabela, a Max(PK)+1função pode ser usada facilmente.

Eu vim procurando a solução desta questão (tinha esquecido a sintaxe) e acabei fazendo minha própria consulta. Engraçado como as coisas funcionam algumas vezes.

Saudações

echo_salik
fonte
2

Se a Chave Primária for Incremento Automático, basta especificar cada campo, exceto a Chave Primária.

INSERT INTO table(field1,field2,field3) SELECT (field1,field2,field3) FROM table WHERE primarykey=1

Veneno Fedy
fonte
2

Atualizei a solução da @ LeonardChallis, pois não funcionou para mim como nenhuma das outras. Eu removi as WHEREcláusulas e SET primaryKey = 0na tabela temporária para que o MySQL incrementasse automaticamente a primaryKey

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable;
UPDATE tmptable SET primaryKey = 0;
INSERT INTO myTable SELECT * FROM tmptable;

Obviamente, isso duplicará todas as linhas da tabela.

D4V1D
fonte
2

Eu usei a técnica de Grim com uma pequena alteração: se alguém procurando por essa consulta é porque não pode fazer uma consulta simples devido ao problema da chave primária:

INSERT INTO table SELECT * FROM table WHERE primakey=1;

Com minha instalação do MySql 5.6.26, a chave não é anulável e produz um erro:

#1048 - Column 'primakey' cannot be null 

Então, depois de criar a tabela temporária, altero a chave primária para ser anulável.

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
ALTER TABLE tmptable_1 MODIFY primarykey int(12) null;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;
Luca Camillo
fonte
alternativamente, nas novas versões do mariadb / mysql, o primaryKey pode ser definido como 0, o que permite que o incremento automático funcione quando inserido.
shelbypereira
2

Eu usaria abaixo,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;
Ishan Liyanage
fonte
1
Isso não funcionará se ITEM_NUMBER for sua chave primária, o que provavelmente ocorrerá nessa situação.
Billy Pilgrim
2

Eu usei no meu banco de dados Koha para inserir itens duplicados com o prefixo 'C' na coluna de código de barras :

INSERT INTO items (`biblionumber`, `biblioitemnumber`, `barcode`, `dateaccessioned` ) SELECT `biblionumber`, `biblioitemnumber`,  CONCAT('C',`barcode`), `dateaccessioned` FROM `items` WHERE barcode='14832';
Rajiv Mahmud
fonte
1

Eu apenas tive que fazer isso e esta foi a minha solução manual:

  1. No phpmyadmin , marque a linha que deseja copiar
  2. Na parte inferior das operações de resultado da consulta, clique em "Exportar"
  3. Na página seguinte, marque 'Salvar como arquivo' e clique em 'Ir'
  4. Abra o arquivo exportado com um editor de texto, encontre o valor do campo primário e altere-o para algo único.
  5. De volta ao phpmyadmin, clique na guia 'Importar' , localize o arquivo para importar o arquivo .sql em Procurar , clique em 'Ir' e a linha duplicada deve ser inserida.

Se você não sabe qual é o campo PRIMARY , olhe novamente para a sua página phpmyadmin , clique na guia 'Estrutura' e, na parte inferior da página, em 'Índices', ele mostrará qual 'Campo' possui um 'Nome-chave' valor 'PRIMARY' .

Um longo caminho, mas se você não quiser lidar com a marcação e apenas precisar duplicar uma única linha, lá está.

user27068
fonte
Bom, responde a operação de uma maneira que é imediata. Obviamente, não funciona para todos os casos, como blobs e dados geoespaciais, mas é muito fácil de executar e funciona para essas mudanças estranhas de bola.
Strixy
1

Esta solução mostrada acima funciona perfeitamente também para linhas selecionadas. Por exemplo, estou criando linhas de demonstração para o meu projeto nice2work, e isso funciona perfeitamente.

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;
DROP TABLE tmptable;

//  You can use this same also directly into your code like (PHP Style)
$sql = "CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;DROP TABLE tmptable;";
Ronald Stevens
fonte
0

Desculpem o necropost, mas foi o que descobri no google e, como achei útil, mas problemático, quis contribuir com uma modificação importante para qualquer um que descobrir isso.

Primeiro, estou usando o SQL Server, não o MySQL, mas acho que deve funcionar da mesma forma. Usei a solução de Leonard Challis porque era mais simples e atendia à necessidade, mas há um problema com isso - se você simplesmente pegar a PK e aumentá-la em 1, o que acontecerá se você tiver adicionado outros registros desde que a linha em questão foi adicionada . Decidi que era melhor deixar o sistema lidar com o incremento automático do PK, então fiz o seguinte:

SELECT * INTO #tmpTable FROM Table WHERE primarykey = 1
--Optionally you can modify one or more fields here like this: 
--UPDATE #tmpTable SET somefield = newData
ALTER TABLE #tmpTable DROP COLUMN TicketUpdateID
INSERT INTO Tickets SELECT * FROM #tmpTable
DROP TABLE #tmpTable

Eu acredito que isso funcionaria da mesma forma no MySQL, mas não posso testar isso, desculpe

maxx233
fonte
1
resposta totalmente bakwaas
AsadYarKhan
0

Eu sei que é uma pergunta antiga, mas aqui está outra solução:

Isso duplica uma linha na tabela principal, supondo que a chave primária seja incrementada automaticamente e cria cópias dos dados das tabelas vinculadas com o novo ID da tabela principal.

Outras opções para obter nomes de colunas:
-SHOW COLUMNS FROM tablename; (Nome da coluna: Campo)
-DESCRIBE tablename (Nome da coluna: Campo)
-SELECT column_name FROM information_schema.columns WHERE table_name = 'tablename' (nome da coluna: column_name)

//First, copy main_table row
$ColumnHdr='';
$Query="SHOW COLUMNS FROM `main_table`;";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
while($Row=mysql_fetch_array($Result))
{
    if($Row['Field']=='MainTableID')     //skip main table id in column list
        continue;
    $ColumnHdr.=",`" . $Row['Field'] . "`";
}
$Query="INSERT INTO `main_table` (" . substr($ColumnHdr,1) . ")
        (SELECT " . substr($ColumnHdr,1) . " FROM `main_table`
            WHERE `MainTableID`=" . $OldMainTableID . ");";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
$NewMainTableID=mysql_insert_id($link);

//Change the name (assumes a 30 char field)
$Query="UPDATE `main_table` SET `Title`=CONCAT(SUBSTRING(`Title`,1,25),' Copy') WHERE `MainTableID`=" . $NewMainTableID . ";";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);

//now copy in the linked tables
$TableArr=array("main_table_link1","main_table_link2","main_table_link3");
foreach($TableArr as $TableArrK=>$TableArrV)
{
    $ColumnHdr='';
    $Query="SHOW COLUMNS FROM `" . $TableArrV . "`;";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
    while($Row=mysql_fetch_array($Result))
    {
        if($Row['Field']=='MainTableID')     //skip main table id in column list, re-added in query
            continue;
        if($Row['Field']=='dbID')    //skip auto-increment,primary key in linked table
            continue;
        $ColumnHdr.=",`" . $Row['Field'] . "`";
    }

    $Query="INSERT INTO `" . $TableArrV . "` (`MainTableID`," . substr($ColumnHdr,1) . ")
            (SELECT " . $NewMainTableID . "," . substr($ColumnHdr,1) . " FROM `" . $TableArrV . "`
             WHERE `MainTableID`=" . $OldMainTableID . ");";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
}
Paulo
fonte
0

O max233 certamente estava no caminho certo, pelo menos no caso de incremento automático. No entanto, não faça a ALTER TABLE. Basta definir o campo de incremento automático na tabela temporária como NULL. Isso apresentará um erro, mas o seguinte INSERT de todos os campos na tabela temporária ocorrerá e o campo automático NULL obterá um valor exclusivo.

user3067083
fonte
0

Crie uma tabela

    CREATE TABLE `sample_table` (
       `sample_id` INT(10) unsigned NOT NULL AUTO_INCREMENT,
       `sample_name` VARCHAR(255) NOT NULL,
       `sample_col_1` TINYINT(1) NOT NULL,
       `sample_col_2` TINYINT(2) NOT NULL,

      PRIMARY KEY (`sample_id`),
      UNIQUE KEY `sample_id` (`sample_id`)

    ) ENGINE='InnoDB' DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

Inserir uma linha

INSERT INTO `sample_table`
   VALUES(NULL, 'sample name', 1, 2);

Clonar inserção de linha acima

INSERT INTO `sample_table`
   SELECT 
    NULL AS `sample_id`, -- new AUTO_INCREMENT PRIMARY KEY from MySQL
    'new dummy entry' AS `sample_name`,  -- new UNIQUE KEY from you
    `sample_col_1`, -- col from old row
    `sample_col_2` -- col from old row
   FROM `sample_table`
   WHERE `sample_id` = 1;

Teste

SELECT * FROM `sample_table`;
Abdullah Aydın
fonte
Nota: Se você está recebendo o erro (# 1048), use '' em vez de NULL
Abdullah Aydın
Sou apenas eu ou é exatamente isso que o OP não queria? (Ou seja, adicionando manualmente todas as colunas à consulta.) #
227
Você está certo, acabei de ler a frase do OP "QUERO copiar uma linha para inserir na mesma tabela", talvez, mesmo assim, isso ainda é útil para "Entrada duplicada 'xxx' para chave ???" erro ^^
Abdullah Aydın
0

Aqui está uma resposta que encontrei on-line neste site Descreve como fazer o acima 1 Você pode encontrar a resposta na parte inferior da página. Basicamente, o que você faz é copiar a linha a ser copiada para uma tabela temporária mantida na memória. Você altera o número da Chave Primária usando a atualização. Em seguida, insira-o novamente na tabela de destino. Você então solta a mesa.

Este é o código para ele:

CRIAR rescueteamMOTOR DE TABELA TEMPORÁRIA = SELEÇÃO DE MEMÓRIA * DE fitnessreport4ONDE rID = 1; linha 1 afetada. ATUALIZAÇÃO rescueteamSET rID = Nulo WHERE rID = 1; linha 1 afetada. INSERT INTO fitnessreport4SELECT * FROM rescueteam; linha 1 afetada. DROP TABLE rescueteam# O MySQL retornou um conjunto de resultados vazio (ou seja, zero
linhas).

Eu criei a equipe de resgate da tabela temporária. Copiei a linha da tabela original fitnessreport4. Em seguida, defino a chave primária da linha na tabela temporária como nula, para que eu possa copiá-la novamente para a tabela original sem obter um erro de Chave duplicada. Eu tentei esse código ontem à noite e funcionou.

user2363682
fonte
0

Esta é uma solução adicional para a resposta "Grim ..." Houve alguns comentários sobre a chave primária como nula. Alguns comentários sobre isso não estão funcionando. E alguns comentários sobre soluções. Nenhuma das soluções funcionou para nós. Temos o MariaDB com a tabela InnoDB.

Não foi possível definir a chave primária para permitir nulo. Usar 0 em vez de NULL levou a um erro de valor duplicado para a chave primária. SET SQL_SAFE_UPDATES = 0;Também não funcionou.

A solução de "Grim ..." funcionou SE mudássemos nossa CHAVE PRIMÁRIA para UNIQUE

Simon
fonte
-1

Só queria postar meu código PHP, porque acho que a maneira como coleciono as colunas é um pouco mais limpa no código do que nos exemplos anteriores. Isso também mostra como você pode alterar facilmente um campo, neste caso adicionando uma string. Mas você também pode substituir um campo de chave estrangeira pelo registro recém-adicionado, caso deseje copiar também alguns registros filhos.

  // Read columns, unset the PK (always the first field in my case)
  $stmt = $conn->prepare('SHOW COLUMNS FROM template');
  $stmt->execute();

  $columns = $stmt->fetchAll();
  $columns = array_map(function ($element) { return $element['Field']; }, $columns);

  unset($columns[0]);

  // Insert record in the database. Add string COPY to the name field.
  $sql = "INSERT INTO `template` (".implode(",", $columns).")";
  if ($key = array_search('name', $columns))
      $columns[$key] = "CONCAT(name, ' COPY')";
  $sql .= " SELECT ".implode(",", $columns)." FROM `template` WHERE `id` = ".$id;

  $stmt = $conn->prepare($sql);
  $stmt->execute();
rolandow
fonte
-2

Para uma solução muito simples, você pode usar o PHPMyAdmin para exportar a linha como um arquivo CSV e simplesmente importar o arquivo CSV alterado. Editando a coluna ID / primarykey para não mostrar valor antes de importá-lo.

SELECT * FROM table where primarykey=1

Então, na parte inferior da página:

insira a descrição da imagem aqui

Onde se diz "Exportar", simplesmente exporte, edite o arquivo csv para remover o valor da chave primária, para que fique vazio e depois importe-o para o banco de dados, uma nova chave primária será atribuída na importação.

Conceder
fonte