Comment copier une ligne et insérer dans la même table avec un champ autoincrement dans MySQL?

j'ai une table Eg - tab . Ce que j'essaie de faire, c'est de copier une ligne avec un identifiant de colonne automatique=1 et d'insérer les données dans la même table avec un identifiant de ligne et de colonne=2.

Utilisant MySql. Comment puis-je faire cela dans une seule requête?S'il vous plaît aider

177
demandé sur mu is too short 2012-02-06 10:26:31

11 réponses

Utiliser INSERT ... SELECT :

insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1

c1, c2, ... sont toutes les colonnes sauf id . Si vous voulez insérer explicitement avec un id de 2 alors inclure cela dans votre liste D'insertion de colonne et votre SELECT:

insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1

vous devrez vous occuper d'un possible duplicata id de 2 dans le second cas bien sûr.

270
répondu mu is too short 2012-02-06 06:31:27

IMO, le meilleur semble utiliser des déclarations sql seulement pour copier cette rangée, tout en se référant en même temps que les colonnes que vous DEVEZ et que vous voulez changer.

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;

Voir aussi av8n.com - comment cloner un enregistrement SQL

prestations:

  • les instructions SQL 2 ne mentionnent que les champs qui doivent être changés pendant le processus de Clonage. Ils ne connaissent pas ou se soucient – autres Fields. Les autres champs ne font que suivre pour le tour, inchangé. Cela rend les instructions SQL plus faciles à écrire, plus faciles à lire, plus faciles à maintenir et plus extensibles.
  • seules les déclarations MySQL ordinaires sont utilisées. Aucun autre outil ou langage de programmation n'est requis.
  • un enregistrement parfaitement correct est inséré dans your_table en une opération atomique.
36
répondu parvus 2012-10-12 06:53:33

dit la table est user(id, user_name, user_email) .

vous pouvez utiliser cette requête:

INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
13
répondu Vijay 2012-02-06 06:35:39

pour une solution rapide et propre qui ne vous oblige pas à nommer des colonnes, vous pouvez utiliser une déclaration préparée comme décrit ici: https://stackoverflow.com/a/23964285/292677

si vous avez besoin d'une solution complexe pour pouvoir le faire souvent, vous pouvez utiliser cette procédure:

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

Vous pouvez l'exécuter avec:

CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');

exemples

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

DISCLAIMER: This la solution est seulement pour quelqu'un qui sera à répétition dupliquer des lignes dans de nombreux tableaux, souvent. Il pourrait être dangereux dans les mains d'un utilisateur malintentionné.

6
répondu curmil 2017-05-23 12:03:06

cela a aidé et il soutient un bloc/des colonnes de texte.

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;
5
répondu Petr Hladík 2018-08-14 04:16:24

vous pouvez également passer dans '0' que la valeur pour la colonne à auto-incrémenter, la valeur correcte sera utilisée lorsque l'enregistrement est créé. C'est tellement plus facile que les tables temporaires.

Source: copier des lignes dans MySQL (voir le deuxième commentaire, par TRiG, à la première solution, par Lore)

2
répondu Mark Pruce 2017-05-23 11:54:50
insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;
2
répondu IR.Programmer 2015-05-15 19:11:18

je cherchais la même fonctionnalité mais je n'utilise pas MySQL. Je voulais copier tous les champs sauf bien sûr la clé primaire (id). Il s'agissait d'une requête d'un seul coup, à ne pas utiliser dans un script ou un code.

j'ai trouvé mon chemin autour avec PL/SQL mais je suis sûr que n'importe quel autre SQL IDE ferait. J'ai fait une base

SELECT * 
FROM mytable 
WHERE id=42;

puis l'exporter vers un fichier SQL où je pourrais trouver le

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (1, 2, 3, ..., 42);

Je l'ai juste édité et utilisé :

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (mysequence.nextval, 2, 3, ..., 42);
0
répondu SabineA 2013-12-03 16:16:27

j'ai tendance à utiliser une variation de ce que mu est trop court posté le:

INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;

aussi longtemps que les tables ont des champs identiques (excepté l'incrément automatique sur la table de journal), alors cela fonctionne bien.

depuis que j'utilise des procédures stockées chaque fois que possible (pour rendre la vie plus facile aux autres programmeurs qui ne sont pas trop familiers avec les bases de données), cela résout le problème de devoir revenir en arrière et mettre à jour les procédures chaque fois que vous ajoutez un nouveau champ à une table.

il garantit également que si vous ajoutez de nouveaux champs à une table ils commenceront à apparaître dans la table de connexion immédiatement sans avoir à mettre à jour vos requêtes de base de données (à moins bien sûr que vous avez certains qui fixent un champ explicitement)

Avertissement: , Vous souhaitez assurez-vous d'ajouter de tout nouveaux champs des deux tables en même temps, de sorte que l'ordre reste le même... sinon, vous allez commencer à avoir des bugs étranges. Si vous êtes le seul cela écrit des interfaces de base de données et vous êtes très prudent alors cela fonctionne bien. Sinon, continuez à nommer tous vos champs.

Note: à la réflexion, à moins que vous travailliez sur un projet solo que vous êtes sûr que vous n'aurez pas d'autres travaillant sur lui coller à la liste de tous les noms de champ explicitement et mettre à jour vos déclarations de journal que votre schéma change. Ce raccourci ne vaut probablement pas le mal de tête à long terme qu'il peut causer... surtout sur un système de production.

0
répondu Privateer 2017-01-09 16:29:10

Dump la ligne que vous voulez sql et ensuite utiliser le SQL généré, moins la colonne ID pour l'importer de nouveau.

0
répondu Claire 2018-01-15 11:01:11
INSERT INTO `dbMyDataBase`.`tblMyTable` 
(
    `IdAutoincrement`, 
    `Column2`, 
    `Column3`, 
    `Column4` 
) 

SELECT 
    NULL,  
    `Column2`, 
    `Column3`, 
    'CustomValue' AS Column4 
FROM `dbMyDataBase`.`tblMyTable` 
WHERE `tblMyTable`.`Column2` = 'UniqueValueOfTheKey' 
; 
/* mySQL 5.6 */
0
répondu Wojciech Skibiński 2018-02-02 01:36:46