2010-12-08 9 views
2

Je dois copier une ligne basée sur une condition (where clause), à ​​partir d'une table, créer une entrée dupliquée dans la même table et mettre à jour une seule colonne (une foreign_key) . Mais parce que "select * from Table_name" retourne tous les champs, y compris primary_key, il n'est pas capable d'insérer une nouvelle ligne error: duplicate key.copier la ligne dans la même table et mettre à jour une seule colonne dans MySQL

Je ne connais pas toutes les colonnes de la table, donc je ne peux pas ignorer primary_key en ne donnant que les noms de colonne requis dans la requête select. Existe-t-il un moyen d'ignorer la clé primaire de la récupération elle-même .. ou puis-je récupérer la ligne entière et définir la valeur de la clé primaire sur null, puis insérer la ligne dans la table afin qu'elle incrémente automatiquement la clé primaire être ajouté.

Merci.

Répondre

5

Il est possible de faire ce que vous voulez en interrogeant les tables de schéma d'informations et en utilisant SQL dynamique pour générer une instruction appropriée. Cependant, vous devriez prendre grand soin avec cette approche, comme la modification des données dans les tables pour lesquelles vous ne connaissez pas les noms de colonnes peut entraîner toutes sortes de problèmes:

DROP TABLE mytable; 

CREATE TABLE `mytable` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `col1` varchar(255) DEFAULT NULL, 
    `col2` varchar(255) DEFAULT NULL, 
    `col3` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

INSERT INTO mytable (col1, col2, col3) VALUES ('A', 'B', 'C'); 

SELECT * FROM mytable; 

+----+------+------+------+ 
| id | col1 | col2 | col3 | 
+----+------+------+------+ 
| 1 | A | B | C | 
+----+------+------+------+ 

SET @columns := (
    SELECT 
    GROUP_CONCAT(column_name) 
    FROM information_schema.columns 
    WHERE table_schema = 'test' 
    AND table_name = 'mytable' 
    AND column_key <> 'PRI' 
); 

SET @sql := (
    SELECT CONCAT(
    'INSERT INTO mytable (', @columns, ') ', 
    'SELECT ', @columns, ' FROM mytable ', 
    'WHERE id = 1;' 
) 
); 

SELECT @sql; 

+---------------------------------------------------------------------------------------+ 
| @sql                     | 
+---------------------------------------------------------------------------------------+ 
| INSERT INTO mytable (col1,col2,col3) SELECT col1,col2,col3 FROM mytable WHERE id = 1; | 
+---------------------------------------------------------------------------------------+ 

PREPARE stmt FROM @sql; 

EXECUTE stmt; 

SELECT * FROM mytable; 

+----+------+------+------+ 
| id | col1 | col2 | col3 | 
+----+------+------+------+ 
| 1 | A | B | C | 
| 2 | A | B | C | 
+----+------+------+------+ 
+0

Merci, Mike .. Pourquoi je ne sais pas la colonne les noms sont parce que, j'écris une procédure stockée générique pour effectuer le même genre d'opération sur plusieurs genres différents de table que j'ai. Donc, je vais juste savoir le nom de la table et "where clause" à utiliser qui sera le même pour toutes les tables. – shailesh

+0

@shailesh: D'accord, l'approche SQL dynamique peut fonctionner pour vous, mais mon avertissement est toujours valable. Bonne chance :-) – Mike

+0

Hey Mike, Il ne semble pas qu'il y ait une meilleure alternative .. J'utilise ceci .. Merci encore .. – shailesh

0

si vous avez des connaissances sur les séquences de la matrice que vous avez, puis après avoir mis une sorte de condition, vous pouvez ignorer le champ qui a la clé primaire.

Vérifiez comme ceci si cela fonctionne

Merci. Comment peut-on savoir quelle est la clé mais ne pas savoir ce que sont les autres colonnes?

0

Si c'est vraiment le cas, je pense que vous devrez écrire du SQL dynamique - ou mieux encore, donner la tâche à quelqu'un qui connaît la structure de la table .

Questions connexes