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
11 réponses
Utiliser INSERT ... SELECT
:
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1
où 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.
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.
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)
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é.
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;
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)
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
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);
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.
Dump la ligne que vous voulez sql et ensuite utiliser le SQL généré, moins la colonne ID pour l'importer de nouveau.
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 */