Dans MySQL, puis-je copier une ligne à insérer dans la même table?


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

Je veux juste copier une ligne à insérer dans le même tableau (c'est-à-dire, je veux dupliquer une ligne existante dans le tableau) mais je veux le faire sans avoir à lister toutes les colonnes après le "select", car ce tableau a trop de colonnes.

Mais quand je fais cela, j'obtiens l'erreur:

Entrée dupliquée 'xxx' pour la clé 1

Je peux gérer cela en créant une autre table avec les mêmes colonnes qu'un conteneur temporaire pour l'enregistrement que je souhaite copier:

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-t-il un moyen plus simple de résoudre ce problème?


J'ai juste un commentaire sur les valeurs codées en dur pour la clé. Je ferais quelque chose comme max(oldtable.id) + oldtable_temp.keyça, je m'assure que les identifiants augmentent et sont uniques.
guy mograbi


@OrganicAdvocate a plus de réponses et plus de vues que cette question
Tiré

Réponses:


189

J'ai utilisé la technique de Leonard Challis avec quelques modifications:

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;

En tant que table temporaire, il ne devrait jamais y avoir plus d'un enregistrement, vous n'avez donc pas à vous soucier de la clé primaire. Le définir sur null permet à MySQL de choisir la valeur elle-même, il n'y a donc aucun risque de créer un doublon.

Si vous voulez être sûr de n'avoir qu'une seule ligne à insérer, vous pouvez ajouter LIMIT 1 à la fin de la ligne INSERT INTO.

Notez que j'ai également ajouté la valeur de clé primaire (1 dans ce cas) à mon nom de table temporaire.


3
Cette solution est correcte (contrairement à d'autres qui ont obtenu des votes) en ce qu'elle permet à MySQL de choisir la valeur de la clé primaire.
Jan Hettich

1
Bien que cela ne fonctionnera pas exactement comme cela est dû à des noms de table temporaires incohérents ( tmptable_1vs. tmptable)
Kieran Tully

9
Comment une clé primaire peut-elle être nulle?
Imran Shafqat

5
S'il est nul, le numéro AI suivant lui est automatiquement attribué lors de son insertion.
Grim ...

3
IMRAN - vous pouvez bien demander. Je pensais que le champ id de la table temporaire n'était peut-être pas automatiquement converti en PK (je suis presque sûr que SQL Server ne le fait pas dans ces circonstances), mais c'est le cas. J'avais besoin de faire ALTER TABLE tmptable_1 MODIFY primarykeyINT NULL; après la première ligne pour faire fonctionner la solution
DJDave

61

Mise à jour 07/07/2014 - La réponse basée sur ma réponse, par Grim ... , est une meilleure solution car elle améliore ma solution ci-dessous, donc je suggère de l'utiliser.

Vous pouvez le faire sans lister toutes les colonnes avec la syntaxe suivante:

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;

Vous pouvez décider de changer la clé primaire d'une autre manière.


16
C'est fondamentalement la même solution que l'OP avait déjà fournie pour son propre problème, bien qu'avec des tables temporaires réelles , et un modèle de création légèrement plus propre. Je pense que le PO a demandé une meilleure approche de ce qu'ils utilisaient déjà, pas un nettoyage de leur syntaxe existante. Je ne comprends pas vraiment tous les votes positifs pour cela.
Sepster

Je vous remercie.
Ça

Est-il nécessaire de supprimer le tmptable une fois ce processus terminé?
SSH ce

"Par défaut, toutes les tables temporaires sont supprimées par MySQL lorsque votre connexion à la base de données est interrompue. Vous voulez toujours les supprimer entre les deux, puis vous le faites en exécutant la commande DROP TABLE." Plus ici
LeonardChallis

Étant donné que vous avez créé le tmptable, vous n'avez pas besoin d'ajouter l' WHERE primarykey = 2instruction pour la dernière ligne. (Ie, just INSERT INTO table SELECT * FROM tmptable.)
Marcus

42

Je suppose que vous voulez que le nouvel album ait un nouveau primarykey? Si primarykeyc'est le cas, AUTO_INCREMENTfaites ceci:

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

... où col1, col2, col3, ...se trouvent toutes les colonnes du tableau à l' exception de primarykey .

Si ce n'est pas une AUTO_INCREMENTcolonne et que vous voulez pouvoir choisir la nouvelle valeur car primarykeyelle est similaire:

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

... où 567est la nouvelle valeur pour primarykey.


41
Comment se fait-il que ce soit voté 7 fois plus alors qu'il ignore la question? ... mais je ne veux pas lister toutes les colonnes après le "select", car ce tableau a trop de colonnes ...
LeonardChallis

7
-1 car c'est précisément ce que l'OP veut éviter. Lisez la question, ou au moins proposez une réponse comme «c'est la seule façon possible».
devios1

5
Parce que parfois la question elle-même est fausse. :) Dupliquer des lignes sans altérer le contenu augmente la redondance. Il est recommandé de changer la structure de la base de données pour minimiser la redondance, si cela est possible.
Torben

5
Ce n'est pas parce que ce n'est pas bien dans les pratiques normales que cela se trompe. Il arrive souvent que les meilleures pratiques standard ne s'appliquent pas. Exemple: la base de données représente des documents et un utilisateur doit conserver une copie d'un document avant d'apporter des modifications.
ima747

6
Parce que vous pourriez atterrir sur cette page ne voulant pas exactement la même chose que l'OP
jx12345

13

Vous l'avez presque eu avec votre première requête, il vous suffit de spécifier les colonnes, de cette façon, vous pouvez exclure votre clé primaire dans l'insertion qui déclenchera l'incrémentation automatique que vous avez probablement sur la table pour créer automatiquement une nouvelle clé primaire pour le entrée.

Par exemple changez ceci:

insert into table select * from table where primarykey=1

Pour ça:

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

N'incluez simplement pas la colonne de clé primaire dans la liste des colonnes pour INSERT ou pour les parties SELECT de la requête.


1
existe-t-il un moyen d'extraire la plupart des colonnes via l'instruction select mais de mettre à jour l'une d'elles manuellement dans la commande d'insertion? comme insert into table ("val1", col2, col3) select col2, col3 from table where primarykey = 1ou quelque chose de similaire?
anon58192932

1
Trouvé! Copiez les valeurs d'une ligne mais ajoutez l'une de vos propres valeurs dans l'instruction d'insertion: stackoverflow.com/questions/23971078/…
anon58192932

1
Désolé vient d'être informé de vos questions, content que vous l'ayez trouvé, c'est bien le chemin.
Braeden Black

9

Vous pouvez également essayer de vider la table, trouver la commande d'insertion et la modifier:

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

Le --skip-extended-insertvous donne une commande d'insertion par ligne. Vous pouvez ensuite trouver la ligne dans votre éditeur de texte préféré, extraire la commande et modifier la clé primaire sur "default".


2
+1 de ma part car il s'agit d'une bonne approche «hors des sentiers battus» qui peut en fait être utile en dehors du temps d'exécution, dans certaines circonstances. Mais c'est principalement la première réponse qui répond en fait à la question du PO et ne modifie pas seulement la syntaxe de la solution déjà fournie par le PO.
Sepster

6

Cette procédure suppose que:

  • vous n'avez pas _duplicate_temp_table
  • votre clé primaire est int
  • vous avez accès pour créer une table

Bien sûr, ce n'est pas parfait, mais dans certains cas (probablement la plupart) cela fonctionnera.

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;

1
+1 Je n'ai pas confirmé cela, worksmais l'approche est solide et a de la valeur car elle est unique ici et répond en fait à la question du PO.
Sepster

5

Ceci peut être réalisé avec une certaine créativité:

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;

Cela aura pour résultat que la nouvelle ligne obtiendra un identifiant incrémenté automatiquement au lieu de l'identifiant de la ligne sélectionnée.


Cela devrait être la réponse acceptée!
Felipe Desiderati

5

Si le champ de clé primaire de votre table est un champ à incrémentation automatique, vous pouvez utiliser une requête avec des colonnes. Par exemple, votre table nommée test_tbla 3 champs comme id, name, age. idest un champ de clé primaire et incrémenté automatiquement, vous pouvez donc utiliser la requête suivante pour dupliquer la ligne:

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

Cette requête entraîne la duplication de chaque ligne.


Si le champ de clé primaire de votre table n'est pas un champ à incrémentation automatique, vous pouvez utiliser la méthode suivante:

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

Le résultat de cette requête est une ligne dupliquée d' id=19inséré en tant que id=20.


C'est la meilleure réponse il y a, le cas est assez simple: INSERT INTO tableName( fieldName1, fieldName2, fieldName3) SELECT fieldName1, fieldName2, fieldName3DE tableNameOU 1 (à copier tous à la fois)
jakubplus

Appuyé - cette réponse est succincte et dans l'esprit de "Copier" une ligne.
user37309

4

ligne de clonage avec champs de mise à jour et valeur d'incrémentation automatique

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`;

@Torben Veuillez cocher la case à gauche de la question (marquez-la comme acceptée) afin que tout le monde sache que cela a fonctionné pour vous.
HosseyNJF

3

Certains des éléments suivants ont été glanés sur ce site. Voici ce que j'ai fait pour dupliquer un enregistrement dans une table avec un nombre quelconque de champs:

Cela suppose également que vous ayez un champ AI au début de la table

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
}

3

J'ai utilisé la technique de Grim avec un petit changement: si quelqu'un recherchant cette requête est parce qu'il ne peut pas faire une requête simple en raison d'un problème de clé primaire:

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

Avec mon installation MySql 5.6.26, la clé n'est pas nullable et génère une erreur:

#1048 - Column 'primakey' cannot be null 

Donc, après avoir créé une table temporaire, je change la clé primaire en une valeur nullable.

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;

alternativement, dans les nouvelles versions de mariadb / mysql, la primaryKey peut être définie sur 0, ce qui permet à l'auto-incrémentation de fonctionner une fois insérée.
shelbypereira

2

Je suis peut-être en retard, mais j'ai une solution similaire qui a fonctionné pour moi.

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

De cette façon, je n'ai pas besoin de créer une table temporaire, etc. Comme la ligne est copiée dans la même table, Max(PK)+1 fonction peut être utilisée facilement.

Je suis venu chercher la solution de cette question (j'avais oublié la syntaxe) et j'ai fini par faire ma propre requête. C'est drôle comment les choses fonctionnent parfois.

Cordialement


2

Si la clé primaire est à incrémentation automatique, spécifiez simplement chaque champ à l'exception de la clé primaire.

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


2

J'ai mis à jour la solution de @ LeonardChallis car elle ne fonctionnait pas pour moi comme aucune des autres. J'ai supprimé les WHEREclauses et SET primaryKey = 0dans la table temporaire pour que MySQL s'incrémente automatiquement le primaryKey

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

Il s'agit bien sûr de dupliquer toutes les lignes du tableau.


2

J'utiliserais ci-dessous,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;

1
Cela ne fonctionne pas si ITEM_NUMBER est votre clé primaire, ce qui est probablement le cas dans ce cas.
Billy Pilgrim

2

J'ai utilisé dans ma base de données Koha pour insérer des éléments en double avec le préfixe `` C '' dans la colonne du code à barres :

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

1

Je devais juste le faire et c'était ma solution manuelle:

  1. Dans phpmyadmin , cochez la ligne que vous souhaitez copier
  2. En bas, sous les opérations de résultat de la requête, cliquez sur "Exporter"
  3. Sur la page suivante, cochez «Enregistrer en tant que fichier» puis cliquez sur «Aller»
  4. Ouvrez le fichier exporté avec un éditeur de texte, recherchez la valeur du champ principal et changez-le en quelque chose d'unique.
  5. De retour dans phpmyadmin, cliquez sur l' onglet 'Importer' , localisez le fichier à importer .sql sous parcourir , cliquez sur 'Go' et la ligne dupliquée doit être insérée.

Si vous ne savez pas ce qu'est le champ PRIMAIRE , revenez sur votre page phpmyadmin , cliquez sur l' onglet 'Structure' et au bas de la page sous 'Index' il vous montrera quel 'Field' a un 'Keyname' valeur 'PRIMAIRE' .

Un peu loin, mais si vous ne voulez pas gérer le balisage et que vous avez juste besoin de dupliquer une seule ligne, vous y allez.


Bien, répond à l'op d'une manière hors de la boîte. Cela ne fonctionne pas pour tous les cas, évidemment, tels que les blobs et les données géospatiales, mais assez facile à retirer et fonctionne pour ces changements de balle étranges.
Strixy le

1

Cette solution montrée ci-dessus fonctionne parfaitement également pour les lignes sélectionnées. Par exemple, je crée des lignes de démonstration pour mon projet nice2work, et cela fonctionne parfaitement.

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;";

0

Désolé pour le necropost, mais c'est ce que j'ai trouvé avec google et comme j'ai trouvé cela utile mais problématique, je voulais apporter une modification importante pour quiconque déterre cela.

Tout d'abord, j'utilise SQL Server, pas MySQL, mais je pense que cela devrait fonctionner de la même manière. J'ai utilisé la solution de Leonard Challis parce qu'elle était la plus simple et répondait au besoin, mais il y a un problème avec cela - si vous prenez simplement le PK et l'incrémentez de 1, que se passe-t-il si vous avez ajouté d'autres enregistrements depuis que la ligne en question a été ajoutée . J'ai décidé qu'il valait mieux laisser le système gérer l'auto-incrémentation du PK, j'ai donc fait ce qui suit:

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

Je pense que cela fonctionnerait de la même manière dans MySQL, mais je ne peux pas le tester, désolé


1
Réponse totalement bakwaas
AsadYarKhan

0

Je sais que c'est une vieille question, mais voici une autre solution:

Cela duplique une ligne dans la table principale, en supposant que la clé primaire est auto-incrémentée, et crée des copies des données des tables liées avec le nouvel identifiant de table principale.

Autres options pour obtenir les noms de colonnes:
-SHOW COLUMNS FROM tablename; (Nom de la colonne: Champ)
-DESCRIBE tablename (Nom de la colonne: Champ)
-SELECT nom_colonne FROM schéma_informations.colonnes WHERE nom_table = 'nom_table' (nom de la colonne: nom_colonne)

//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__);
}

0

max233 était certainement sur la bonne voie, du moins pour le cas de l'auto-incrémentation. Cependant, ne faites pas le ALTER TABLE. Définissez simplement le champ d'auto-incrémentation dans la table temporaire sur NULL. Cela présentera une erreur, mais l'INSERT suivant de tous les champs de la table temporaire se produira et le champ automatique NULL obtiendra une valeur unique.


0

Créer une table

    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';

Insérer une ligne

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

Insertion de ligne de clonage ci-dessus

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;

Tester

SELECT * FROM `sample_table`;

Remarque: Si vous obtenez une erreur (# 1048), utilisez '' au lieu de NULL
Abdullah Aydın

Est-ce juste moi ou est-ce exactement ce que le PO ne voulait pas ? (C'est-à-dire ajouter manuellement chaque colonne à la requête.)
Byson

Vous avez raison, je viens de lire la phrase "I JUST want to copy one row to insert in the same table" de OP, peut-être, de toute façon cela est toujours utile pour "Dupliquer l'entrée 'xxx' pour la clé ???" error ^^
Abdullah Aydın

0

Voici une réponse que j'ai trouvée en ligne sur ce site Décrit comment faire ce qui précède 1 Vous pouvez trouver la réponse au bas de la page. En gros, vous copiez la ligne à copier dans une table temporaire conservée en mémoire. Vous modifiez ensuite le numéro de clé primaire à l'aide de la mise à jour. Vous le réinsérez ensuite dans la table cible. Vous déposez ensuite la table.

Voici le code pour cela:

CREATE TEMPORARY TABLE rescueteamENGINE = MEMORY SELECT * FROM fitnessreport4WHERE rID = 1; ligne # 1 affectée. UPDATE rescueteamSET rID = Null WHERE rID = 1; # 1 ligne affectée.INSERT INTO fitnessreport4SELECT * FROM rescueteam; # 1 ligne affectée. DROP TABLE rescueteam# MySQL a renvoyé un jeu de résultats vide (c'est-à-dire zéro ligne
).

J'ai créé la rescueteam de table temporaire. J'ai copié la ligne de mon tableau de fitnessreport4 d'origine. J'ai ensuite défini la clé primaire de la ligne dans la table temporaire sur null afin de pouvoir la recopier dans la table d'origine sans obtenir une erreur de clé en double. J'ai essayé ce code hier soir et cela a fonctionné.


0

Ceci est une solution supplémentaire à la réponse de "Grim ..." Il y a eu quelques commentaires sur le fait d'avoir une clé primaire comme null. Certains commentaires à ce sujet ne fonctionnent pas. Et quelques commentaires sur les solutions. Aucune des solutions n'a fonctionné pour nous. Nous avons MariaDB avec la table InnoDB.

Nous n'avons pas pu définir la clé primaire pour autoriser null. L'utilisation de 0 au lieu de NULL entraînait une erreur de valeur en double pour la clé primaire. SET SQL_SAFE_UPDATES = 0;Cela n'a pas fonctionné non plus.

La solution de "Grim ..." a fonctionné SI nous avons changé notre clé PRIMAIRE en UNIQUE à la place


-1

Je voulais juste publier mon morceau de code PHP, car je pense que la façon dont je collecte les colonnes est un peu plus propre dans le code que les exemples précédents. Cela montre également comment vous pouvez facilement modifier un champ, dans ce cas en ajoutant une chaîne. Mais vous pouvez également remplacer un champ de clé étrangère par l'enregistrement nouvellement ajouté, au cas où vous souhaiteriez également copier certains enregistrements enfants.

  // 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();

-2

Pour une solution très simple, vous pouvez utiliser PHPMyAdmin pour exporter la ligne sous forme de fichier CSV, puis importer simplement le fichier CSV modifié. Modification de la colonne ID / clé primaire pour n'afficher aucune valeur avant de l'importer.

SELECT * FROM table where primarykey=1

Puis en bas de page:

entrez la description de l'image ici

Où est dit "Exporter", exportez simplement, puis éditez le fichier csv pour supprimer la valeur de la clé primaire, donc c'est vide, puis importez-la simplement dans la base de données, une nouvelle clé primaire sera attribuée lors de l'importation.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.