2010-01-18 17 views
4

J'ai une table Mysql avec une seule clé primaire (appelée pkey) qui incrémente automatiquement, et je voudrais cloner une ligne, en gardant toutes les données identiques, sauf pour la clé primaire qui devrait devient la prochaine valeur disponible définie par l'incrémentation automatique.Mysql Clone Row avec clé primaire

Ma première question est, la requête suivante est-elle possible?

UPDATE `table` SET pkey='next_available_primary_key' WHERE pkey='old_primary_key' 

si ont essayé

UPDATE `table` SET pkey=null WHERE pkey='old_primary_key' 

Mais il définit seulement la valeur de la clé primaire à zéro. Merci d'avance pour toute aide/suggestion.

MISE À JOUR:

Je suppose que je dois ajouter que je ne veux pas vraiment deux copies des données du tableau. Je veux juste changer la clé primaire. Donc, si je devais utiliser SELECT INSERT je dois compenser par la commande DUPLICATE KEY UPDATE pkey = « next_available_primary_key » je ne suis pas sûr comment faire ...

+0

Par curiosité: Quel est votre objectif ? Parce que vous utilisez peut-être mal la clé primaire pour un objectif (comme les données de commande) pour lequel il n'est pas destiné. –

Répondre

3
insert into t select 0,a,b,c,d,e from t where id = some_id 

utilisation 0 comme valeur pour le auto_increment colonne, MySQL utilisera le prochain disponible ...

édité pour votre nouveau commentaire, si vous voulez changer l'ID à la suivante disponible,

update tbl set id = (select auto_increment from 
    information_schema.tables where table_name = 'tbl') where id = 4; 
7

vous voulez INSERT, UPDATE pas, si vous essayez de faire une nouvelle rangée dans la table.

Que pensez-vous de cela? Assurez-vous que votre PKEY est réglé sur auto-incrémentation.

INSERT INTO `table` (col,col,col) /*name all the columns EXCEPT the primary key*/ 
SELECT col,col,col /*name all the columns EXCEPT the primary key*/ 
    FROM 'table` 
WHERE pkey='old_primary_key' 
+0

Donc j'ai pensé à cela, et je peux utiliser cette solution, mais j'espérais une solution plus propre où je n'ai pas besoin d'énumérer tous les champs, sauf pour la clé primaire. –

+2

Je fais beaucoup de ce genre de choses, et j'utilise les métadonnées (information_schema.COLUMNS) pour construire ma requête. COLONNES.COLUMN_KEY = 'PRI' si cette colonne fait partie de la clé primaire de la table, chaîne vide si ce n'est pas le cas. –

+0

De toute façon, vous devrez utiliser un script pour construire la requête. Et je pense que vous devrez utiliser une table temporaire également en fonction de votre moteur de base de données. –

2

Que diriez-vous de la solution trouvée sur clone-sql-record?

CREATE TEMPORARY TABLE %1 ENGINE=MEMORY SELECT * FROM mytable WHERE myid=%2; 

UPDATE %1 SET myid=%3; 

INSERT INTO mytable SELECT * FROM %1; 

DROP TABLE %1; 

  • % 1 est "T" + raw_time_stamp, ex T20120124132754
  • % 2 est oldid
  • % 3 est newid
0

enregistrements clone de table, avec clé primaire auto-incrémentée

CREATE TEMPORARY TABLE `tmp` SELECT * FROM `your_table_name`; 

UPDATE `tmp` SET id = NULL ; 

INSERT INTO `your_table_name` SELECT * FROM `tmp`; 

DROP TEMPORARY TABLE IF EXISTS `tmp`; 
0

Notez que les autres solutions données semblent fonctionner sur une table source qui autorise null pour la colonne de clé primaire. Comme ce n'est pas le cas pour moi, je suis tombé sur une erreur - qui peut être facilement résolu en modifiant la table temporaire (je pensais id être la clé primaire):

CREATE TEMPORARY TABLE tmp_clone ENGINE=MEMORY 
    SELECT * FROM my_source_table WHERE id=some_id; 

ALTER TABLE tmp_clone MODIFY id bigint(20) default null; 
UPDATE tmp_clone SET id=null; 

INSERT INTO my_source_table SELECT * FROM tmp_clone; 

DROP TABLE tmp_clone; 

SELECT * from my_source_table where id = last_insert_id();