Réponses:
Utilisation 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 souhaitez insérer explicitement avec un id
de 2, incluez-le dans votre liste de colonnes INSERT et votre SELECT:
insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1
Vous devrez id
bien sûr vous occuper d'un éventuel doublon de 2 dans le second cas.
OMI, le meilleur semble utiliser les instructions sql uniquement pour copier cette ligne, tout en référençant uniquement les colonnes que vous devez et souhaitez modifier.
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
Avantages:
your_table
dans une opération atomique.Error Code: 1113. A table must have at least 1 column
.
SET id=NULL
peut provoquer une erreur Column 'id' cannot be null
. Devrait être remplacé parUPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
Disons que 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)
Result: near "SELECT": syntax error
Cela a aidé et prend en charge les colonnes 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;
Pour une solution rapide et propre qui ne vous oblige pas à nommer des colonnes, vous pouvez utiliser une instruction 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
AVIS DE NON-RESPONSABILITÉ: Cette solution est uniquement pour quelqu'un qui va souvent dupliquer des lignes dans de nombreuses tables, souvent. Cela pourrait être dangereux entre les mains d'un utilisateur voyou.
Vous pouvez également passer «0» comme valeur pour la colonne à incrémenter automatiquement, la valeur correcte sera utilisée lors de la création de l'enregistrement. C'est tellement plus facile que les tables temporaires.
Source: Copie de lignes dans MySQL (voir le deuxième commentaire, par TRiG, à la première solution, par Lore)
Beaucoup de bonnes réponses ici. Voici un exemple de la procédure stockée que j'ai écrite pour accomplir cette tâche pour une application Web que je développe:
-- 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;
Si vous pouvez utiliser MySQL Workbench, vous pouvez le faire en cliquant avec le bouton droit sur la ligne et en sélectionnant «Copier la ligne», puis en cliquant avec le bouton droit sur la ligne vide et en sélectionnant «Coller la ligne», puis en changeant l'ID, puis en cliquant sur «Appliquer».
Copiez la ligne:
Collez la ligne copiée dans la ligne vierge:
Modifiez l'ID:
Appliquer:
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 unique, à ne pas utiliser dans un script ou un code.
J'ai trouvé mon chemin avec PL / SQL mais je suis sûr que n'importe quel autre IDE SQL ferait l'affaire. J'ai fait un basique
SELECT *
FROM mytable
WHERE id=42;
Ensuite, exportez-le dans 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 qui est trop court:
INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;
Tant que les tables ont des champs identiques (à l'exception de l'incrémentation automatique sur la table de journal), cela fonctionne bien.
Puisque j'utilise des procédures stockées autant que possible (pour faciliter la vie à d'autres programmeurs qui ne sont pas trop familiers avec les bases de données), cela résout le problème d'avoir à 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 immédiatement dans la table de journal sans avoir à mettre à jour vos requêtes de base de données (à moins bien sûr que certains en définissent explicitement un champ)
Avertissement: vous voudrez vous assurer d'ajouter tous les nouveaux champs aux deux tables en même temps afin que l'ordre des champs reste le même ... sinon vous commencerez à obtenir des bogues impairs. Si vous êtes le seul à écrire des interfaces de base de données ET que vous êtes très prudent, cela fonctionne bien. Sinon, tenez-vous à nommer tous vos champs.
Remarque: Après réflexion, à moins que vous ne travailliez sur un projet solo, vous en serez sûr que d'autres n'y travailleront pas pour répertorier explicitement tous les noms de champs et mettre à jour vos instructions de journal à mesure 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.
INSÉRER DANS `dbMyDataBase`.`tblMyTable` ( `IdAutoincrement`, `Colonne2`, `Colonne3`, `Colonne4` ) SÉLECTIONNER NUL, `Colonne2`, `Colonne3`, 'CustomValue' AS Column4 FROM `dbMyDataBase`.`tblMyTable` OERE `tblMyTable`.`Column2` = 'UniqueValueOfTheKey' ; / * mySQL 5.6 * /