2012-10-17 4 views
1

Mon problème est très simple à expliquer mais je n'arrive pas à trouver la bonne réponse!Copier et insérer plusieurs fois dans (mysql)?

J'ai 3 tables dans mysql, appelées tA, tB, tC. J'ai une entrée A tA, 2 entrées B en tB et 3 entrées C en tC avec une architecture hiérarchique comme celui-ci:

  A 
      | 
    ---------------- 
    |    | 
    B1    B2 
    |    | 
--------   | 
|  |   | 
C1  C2   C3 

Comme vous pouvez l'imaginer, je les entrées B sont liées à une entrée avec un identifiant , et les entrées C sont liées aux entrées B avec B id.

Je veux simplement copier ces données:

  A' 
      | 
    ---------------- 
    |    | 
    B1'   B2' 
    |    | 
--------   | 
|  |   | 
C1' C2'   C3' 

Donc au début, je commence par la création de A « et copier les entrées B liées à A ». Pas de soucis. Mais après, j'ai fait une requête avec une jointure gauche pour copier les entrées C vers C '. Ça marche presque ... le seul problème est que, de cette façon, mes entrées C 'sont liées à B id et non à B' id !!!!

J'essaie d'autres choses mais je ne sais pas comment faire ça. Cela semble si simple. Peut-être que je suis fatigué ... Peut-être que je dois copier les entrées B une par une, et copier toutes les entrées C de l'entrée B en cours avant de passer à la suivante.

Mais n'y a-t-il pas une façon plus intelligente de le faire? Avec insert_id, cascade, trigger, clé étrangère ???

Je ne suis pas un spécialiste de sql et j'espère que quelqu'un ici aura une bonne solution.

Merci d'avance.

Bastien

+0

Je ne peux pas vraiment penser à une façon purement SQL pour faire cela, mais je pourrais facilement le gérer avec PHP ou ColdFusion. Utilisez-vous n'importe quel type d'application pour accéder à votre base de données? si oui, quelle langue et je vais essayer de vous aider. – invertedSpear

+0

Mon application est basée sur CodeIgniter (php). J'utilise fondamentalement ActiveRecord mais parfois pour des demandes complexes, j'utilise directement la requête avec SQL natif. Merci de votre aide. – bastien

Répondre

0

La méthode d'Alain est une façon possible de gérer cela uniquement en SQL, mais nécessite quelques modifications de table, en stockant essentiellement l'ID original qu'un objet a été copié de.

Donc, vous avez dit que vous utilisez PHP, et je voudrais pouvoir vous donner des exemples plus pertinents, mais j'ai été loin de PHP trop longtemps. Mais vous devriez être capable de faire ce qui suit.

  1. Get A de la base de données, stocker un identifiant dans une variable en php (suggérer oldAID $)
  2. Copie A propriétés et stocker de retour à la DB comme A »
  3. Get Last Insérer ID et enregistrer comme variable (suggèrent $ newAID)
  4. Obtenir tous les enregistrements B de DB où parent = $ oldAID
  5. boucle à travers les enregistrements b, stocker les enregistrements en cours id comme oldBID $
  6. Copier B1 possédante et stocker de retour à DB B1 'avec un parent id $ newAID
  7. Obtenez dernier magasin insertid comme newBID $
  8. Obtenez tous les enregistrements C de DB où parent ID = $ oldBID
  9. Faire des copies et stockons Retour à la DB avec ID parent = $ newBID
  10. Itterate par votre boucle a commencé À l'étape 5

En utilisant PHP pour garder un œil sur votre dernier ID d'insertion, vous pouvez effectuer les copies dont vous avez besoin et les garder précises. Inconvénient à cela, il y a beaucoup de va-et-vient entre php et MySQL donc dans un très grand ensemble, cela irait à plusieurs niveaux de profondeur, un processus comme celui-ci peut prendre quelques secondes. Mais si vos ensembles normaux sont aussi petits et peu profonds que votre exemple, cela ne devrait pas être trop mauvais.

+0

Merci. C'est la solution que j'ai trouvée et écrite dans ma question. Donc, je pense que je vais le garder. Semble être le seul. Ce que je pensais, en postant la question sur SO, était qu'il pourrait y avoir eu une solution comme un CASCADE DE SUPPRIMER mais pour insérer. Cela ne semble pas! Merci de votre aide. – bastien

0

Ajouter une colonne à votre deuxième série de tableaux qui contiennent l'ID de l'ensemble d'origine. Après avoir créé A ', vous pouvez utiliser les ID d'origine pour créer les entrées B'. Ensuite, utilisez les ID originaux de B 'pour créer C'.

Avez-vous du sens? Donc, avec plus d'informations de @bastien, je suggère d'ajouter une colonne à tableA appelée quelque chose comme old_id. Lorsque vous insérez vos lignes copiées, mettez l'original id dans old_id. Vous pouvez ensuite utiliser old_id pour trouver les lignes correspondantes dans tableB, tableC, etc.

+0

Les tables sont identiques. Juste les entrées sont copiées. J'explique: à la fin, vous A et A 'dans tA, B1, B2, B1' et B2 'dans tB et C1, C2, C3, C1', C2 ', C3' dans tC. Et la copie est une commande temporaire. Je n'ai pas besoin de garder que A 'est une copie de A. Donc, l'ajout d'une colonne qui n'est utilisée que pour copier dans chaque table me semble un peu codé en dur. Je vais y réfléchir ... Mais merci pour la réponse – bastien

+0

Le fait est que vous avez besoin d'un moyen d'accéder à la fois les valeurs «A» et «A» lorsque vous travaillez avec les tables ultérieures. La colonne supplémentaire vous donne cette capacité. Il y a probablement d'autres façons, aussi. Bonne chance. –

+0

Je ne comprends pas ce que vous voulez dire par "tables postérieures". Il n'y a pas un deuxième ensemble de tables. Il n'y a qu'un seul ensemble avec les tables tA, tB et tC. Pouvez-vous expliquer ce point? – bastien

Questions connexes