2010-08-04 5 views
3

J'ai 3 tables, réseaux, noeuds, noeuds réseau, connexions réseau. Networknodes a 3 champs network_node_id, network_id, et node_id, les deux derniers sont des références clé forien au réseau. et un réseau peut inclure plusieurs copies du même noeud (mais avec network_node_id diffrent)Procédure stockée MySQL pour dupliquer des enregistrements à partir de 4 tables inter-reliées

networkconnections a les fileds networkconnection_id, start_network_node_id, end_network_node_id

Maintenant, je veux dupliquer une entrée de réseau, ce qui inclut la création d'un nouveau réseau enregistrement de table, création de copies d'enregistrements dans networknodes et networkconnections.

Comment cela peut-il être fait avec les procédures stockées MySQL? Est-il possible de le faire dans une seule requête sans utiliser de tableaux et de boucles?

DROP PROCEDURE IF EXISTS `DuplicateNetwork`; 

CREATE PROCEDURE `DuplicateNetwork`(network_key char(50)) 
BEGIN 
    DECLARE newNetworkId BINARY(16); 

    // Generate a Unique using function 
    SELECT NewKey() INTO newNetworkId; 
    // Create a new Network 
    INSERT INTO networks (network_id, 
     Label, 
     AppBackgroundColorKey, 
     DateAdded,LastModified) 
     SELECT newNetworkId, 
      Label,AppBackgroundColorKey, 
      DateAdded, 
      NOW(), 
     FROM networks 
     WHERE network_id = network_key; 
    // Copy networknodes reords curresponding to network_key  
    // Store the ids of newly created recored to an array or some other structure called NN 
    INSERT INTO networknodes (
       network_node_id, 
       network_id, 
       node_id, 
       DateAdded, 
       LastModified) 
      SELECT NewKey(), // Need to dtore this value in NN 
        newNetworkId, 
        node_id, 
        DateAdded, 
        NOW() 
      FROM networknodes 
     WHERE network_id = network_key; 

    // Copy networkconnections reords curresponding to network_key 
    // This part is incorrect, i don't know how two make it, help is needed here  
    INSERT INTO networkconnections(networkconnection_id, 
      start_network_node_id, 
      end_network_node_id, 
      DateAdded) 
      SELECT NewKey(), 
      (SELECT NWN_start.network_node_id ...), 
      (SELECT NWN_end.network_node_id ...), 
      FROM networkconnection 
      INNER JOIN networknodes AS NWN_start ON networkconnection.start_network_node_id=NWN_start.network_node_id 
      INNER JOIN networknodes AS NWN_end ON networkconnection.end_network_node_id =NWN_end.network_node_id 
      //WHERE NWN_start.networl_id = network_key; 
    // For each room network connection 
     replace the old networknode_id with new networknode_id for both start and end nodes 
END; 

Serait greatful Tout organisme peut améliorer/compléter l'algorithme

+0

Votre proc existant a une erreur. Qu'est-ce que newRoomId dans la table des réseaux? – Manjoor

+0

@Manjoor, merci pour cela, je l'ai corrigé –

+0

Pourriez-vous montrer vos tableaux (ou les parties pertinentes d'entre eux, s'ils sont grands)? –

Répondre

1

Oui, créer une table temporaire pour contenir les valeurs que vous copiez, vous pouvez garder une référence aux anciennes valeurs. Gardez la première requête, puis faites:

CREER tmpNetworkNodes TEMPORAIRES TABLE ( ... schéma ici ... )

INSERT INTO tmpNetworkNodes 
     SELECT NewKey() as newNetworkKey, // Need to dtore this value in NN 
       newNetworkId, 
       newNodeId() as newNodeId 
       node_id as oldNodeId, 
       DateAdded 
     FROM Networknodes 
     WHERE network_id = network_key; 

INSERT INTO networknodes (
      network_node_id, 
      network_id, 
      node_id, 
      DateAdded, 
      LastModified) 
SELECT newNetworkKey, newNetworkId, newNodeId, DateAdded, Now() 
     from tmpNetworkNodes 

INSERT INTO networkconnections(
     networkconnection_id, 
     start_network_node_id, 
     end_network_node_id, 
     DateAdded) 
SELECT NewKey(), 
     NWN_start.newNodeId, 
     NWN_end.newNodeId, 
    FROM networkconnection 
     INNER JOIN tmpNetworkNodes AS NWN_start 
     ON networkconnection.start_network_node_id=NWN_start.oldNodeId 
     INNER JOIN tmpNetworknodes AS NWN_end 
     ON networkconnection.end_network_node_id =NWN_end.oldNodeId 

DROP TABLE TEMPORAIRES tmpNetworkNodes

Parce que la table temporaire contient seulement les éléments du réseau qui vous intéresse, les jointures internes de la dernière requête filtreront tout ce qui provient des autres réseaux.

Je suppose que vous avez une fonction pour newNodeId comme vous le faites pour networkKey(), donc aucune des colonnes n'est identity/autoincrement. Je peux également avoir tort votre schéma, car il est difficile de suivre les relations sans les spécifications de la table complète.

J'espère que ça aide!

Questions connexes