2009-08-30 6 views
66

J'ai deux tables avec la structure identique excepté une colonne ... Le tableau 2 a cette colonne supplémentaire dans laquelle j'insérerais le CURRENT_DATE()MYSQL: Comment copier une ligne entière d'une table à une autre dans mysql avec la deuxième table ayant une colonne supplémentaire?

Je voudrais copier toutes les valeurs de table1 à table2.

si j'utilise

INSERT INTO dues_storage SELECT * FROM dues WHERE id=5; 

il renvoie une erreur indiquant la différence dans le nombre de colonnes.

J'ai deux questions sur ce point:

  1. Comment puis-je contourner cela?
  2. et comment puis-je ajouter la valeur de la colonne de date supplémentaire (CURRENT_DATE()) dans la table 2 dans cette même instruction?
+0

Vous pourriez jeter un coup d'oeil à ceci. Cela a fonctionné pour moi dans mysql. http://stackoverflow.com/questions/57168/how-to-copy-a-row-from-one-sql-server-table-to-another – Shreyo

Répondre

79

Pour affiner la réponse de Zed, et pour répondre à votre commentaire:

INSERT INTO dues_storage 
SELECT d.*, CURRENT_DATE() 
FROM dues d 
WHERE id = 5; 

Voir T.J. Le commentaire de Crowder

+43

Soyez ** TRÈS PRUDENT ** en faisant cela. Cela fonctionne, mais il suppose que l'ordre des colonnes dans les deux tables est identique; il ne correspond pas ** au nom de la colonne, et essaie de contraindre les valeurs à s'adapter, ce qui peut provoquer des résultats inattendus. Maintenant, si votre structure de développement assure que les ordres de colonne sont identiques à la dernière colonne, c'est une façon simple et pratique de le faire, mais la mise en garde est importante. –

+0

Heureusement, la commande est la même. Gardez à l'esprit de garder la structure identique même dans le futur. Merci a tous! – user165242

+0

@crunchdog comment la requête devrait-elle être organisée si je dois définir 'where' comme' A.id = B.id'? – Eugene

8
INSERT INTO dues_storage 
SELECT field1, field2, ..., fieldN, CURRENT_DATE() 
FROM dues 
WHERE id = 5; 
+0

il y a tellement de champs dans la table, il y a plus court chemin? Si je change la structure de la table là, je devrais me rappeler de changer les pages de php aussi. – user165242

+0

vous pouvez y échapper avec des cotisations. * – Zed

44

Le moyen le plus sûr de le faire est de spécifier complètement les colonnes à la fois pour l'insertion et l'extraction. Il n'y a aucune garantie (à l'application) que l'un ou l'autre de ces derniers sera l'ordre que vous pensez qu'ils peuvent être.

insert into dues_storage (f1, f2, f3, cd) 
    select f1, f2, f3, current_date() from dues where id = 5; 

Si vous êtes inquiet d'avoir à changer beaucoup de plusieurs pages PHP qui font (comme vous semblez indiquer dans le commentaire à une autre réponse), c'est mûr pour une procédure stockée. De cette façon, toutes vos pages PHP appellent simplement la procédure stockée avec (par exemple) juste l'ID à copier et elle contrôle le processus de copie réel. De cette façon, il n'y a qu'un seul endroit où vous devez maintenir le code, et, à mon avis, le SGBD est le bon endroit pour le faire.

+0

ouais .. mais je commence juste. Je dois maintenant savoir quelles sont les procédures stockées, merci! une chose de plus à apprendre aujourd'hui! – user165242

4

J'espère que cela aidera quelqu'un ... Voici un petit script PHP que j'ai écrit au cas où vous auriez besoin de copier certaines colonnes mais pas d'autres, et/ou les colonnes ne sont pas dans le même ordre sur les deux tables. Tant que les colonnes portent le même nom, cela fonctionnera. Donc si la table A a [userid, handle, quelquechose] et que tableB a [userID, handle, timestamp], alors vous "SELECT userID, handle, NOW() comme timestamp FROM tableA", puis obtenez le résultat de cela, et passe le résultat en tant que premier paramètre à cette fonction ($ z). $ toTable est un nom de chaîne pour la table à laquelle vous copiez, et $ link_identifier est la base de données à laquelle vous copiez. Ceci est relativement rapide pour les petits ensembles de données. Pas suggéré que vous essayez de déplacer plus de quelques milliers de lignes à la fois de cette façon dans un cadre de production. Je l'utilise principalement pour sauvegarder les données collectées au cours d'une session lorsqu'un utilisateur se déconnecte, puis efface immédiatement les données de la base de données dynamique pour le maintenir à jour.

function mysql_multirow_copy($z,$toTable,$link_identifier) { 
      $fields = ""; 
      for ($i=0;$i<mysql_num_fields($z);$i++) { 
       if ($i>0) { 
        $fields .= ","; 
       } 
       $fields .= mysql_field_name($z,$i); 
      } 
      $q = "INSERT INTO $toTable ($fields) VALUES"; 
      $c = 0; 
      mysql_data_seek($z,0); //critical reset in case $z has been parsed beforehand. ! 
      while ($a = mysql_fetch_assoc($z)) { 
       foreach ($a as $key=>$as) { 
        $a[$key] = addslashes($as); 
        next ($a); 
       } 
       if ($c>0) { 
        $q .= ","; 
       } 
       $q .= "('".implode(array_values($a),"','")."')"; 
       $c++; 
      } 
      $q .= ";"; 
      $z = mysql_query($q,$link_identifier); 
      return ($q); 
     } 
-4

J'ai essayé ce que vous avez dit, mais je reçois un message qui dit qu'il ya un problème avec la clause where

ce que j'ai essayé:

INSERT INTO `seller` SELECT FROM `seller_test` WHERE 
`s_code`=11; 

erreur:

> #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use 
> near 'FROM `seller` WHERE `s_code`=11' at line 1 

mais quand j'ai ajouté le * après SELECT mot-clé et la requête est devenue comme ceci:

INSERT INTO `seller` SELECT ***** FROM `seller_test` WHERE 
`s_code`=11; 

i obtenir un bon résultat alors essayez d'ajouter * après le mot-clé SELECT

-2

Je voulais juste ajouter ce petit bout qui fonctionne à merveille pour moi.

INSERT INTO your_target_table SELECT * à partir de your_rescource_table WHERE id = 18;

Et pendant que je suis à lui donner un grand cri à Sequel Pro, si vous ne l'utilisez pas, je vous recommande fortement de le télécharger ... rend la vie beaucoup plus facile

0

Vous pouvez également utiliser Inner Requêtes pour le faire.

SQL> INSERT INTO <NEW_TABLE> SELECT * FROM CUSTOMERS WHERE ID IN (SELECT ID FROM <OLD_TABLE>); 

Espérons que cela aide!

Questions connexes