web-dev-qa-db-fra.com

MYSQL: Comment copier une ligne entière d'une table à une autre dans mysql avec la seconde table ayant une colonne supplémentaire?

J'ai deux tables de structure identique à l'exception d'une colonne ... La table 2 contient cette colonne supplémentaire dans laquelle je voudrais insérer le CURRENT_DATE ()

Je voudrais copier toutes les valeurs de table1 à table2.

si j'utilise

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

cela jette une erreur indiquant la différence de nombre de colonnes. 

J'ai deux questions à ce sujet:

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

Pour préciser la réponse de Zed et répondre à votre commentaire:

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

Voir T.J. Commentaire de Crowder

84
crunchdog

Le moyen le plus sûr de le faire est de spécifier complètement les colonnes pour l'insertion et l'extraction. Rien ne garantit (à l’application) que l’un ou l’autre de ces ordres sera celui que vous pensez être.

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

Si vous craignez de devoir changer plusieurs pages PHP qui le font (comme vous semblez l'indiquer dans le commentaire en réponse), cette procédure est prête pour une procédure stockée. Ainsi, toutes vos pages PHP appellent simplement la procédure stockée avec (par exemple) uniquement l'ID à copier, ce qui contrôle le processus de copie. De cette façon, il n’ya qu’un seul endroit où vous devez gérer le code et, à mon avis, le SGBD est le bon endroit pour le faire.

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

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 tableaux. Tant que les colonnes portent le même nom, cela fonctionnera. Donc, si la table A a [userid, handle, quelque chose] et que la tableB a [userID, handle, timestamp], alors vous devez "SELECT ID utilisateur, handle, NOW () comme timestamp FROM tableA", puis obtenir le résultat, passe le résultat comme premier paramètre de cette fonction ($ z). $ toTable est un nom de chaîne pour la table que vous copiez, et $ link_identifier est la base de données vers laquelle vous copiez. C'est relativement rapide pour de petits ensembles de données. Il n'est pas suggéré d'essayer de déplacer plus de quelques milliers de lignes à la fois de cette façon dans un contexte de production. J'utilise principalement cette option pour sauvegarder les données collectées au cours d'une session lorsqu'un utilisateur se déconnecte, puis effacer immédiatement les données de la base de données en direct pour la maintenir mince.

 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
Josh Strike
SET @sql = 
CONCAT( 'INSERT INTO <table_name> (', 
    (
        SELECT GROUP_CONCAT( CONCAT('`',COLUMN_NAME,'`') ) 
            FROM information_schema.columns 
            WHERE table_schema = <database_name>
                AND table_name = <table_name>
                AND column_name NOT IN ('id')
    ), ') SELECT ', 
    ( 
        SELECT GROUP_CONCAT(CONCAT('`',COLUMN_NAME,'`')) 
        FROM information_schema.columns 
        WHERE table_schema = <database_name>
            AND table_name = <table_source_name>
            AND column_name NOT IN ('id')  
    ),' from <table_source_name> WHERE <testcolumn> = <testvalue>' );  

PREPARE stmt1 FROM @sql; 
execute stmt1;

Bien sûr, remplacez les valeurs <> par des valeurs réelles et observez vos citations.

0
Joomsavvy

Vous pouvez également utiliser Inner Queries pour le faire.

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

J'espère que cela t'aides!

0
Prasheel