2010-05-19 4 views
0

Utilisation de MS SQL 2005,Utiliser SQL pour cloner des données dans deux tables qui ont une relation 1-1 entre eux

Tableau 1

ID | T1Value | T2ID | GroupID 
---------------------------------- 
1 |  a  | 10 |  1 
2 |  b  | 11 |  1 
3 |  c  | 12 |  1 
4 |  a  | 22 |  2 

Tableau 2

ID | T2Value 
---------------- 
10 |  H 
11 |  J 
12 |  K 
22 |  H 

Je veux pour cloner les données pour GroupID == 1 dans un nouveau GroupID afin que je résulte avec ce qui suit:

Tableau 1

ID | T1Value | T2ID | GroupID 
---------------------------------- 
1 |  a  | 10 |  1 
2 |  b  | 11 |  1 
3 |  c  | 12 |  1 
4 |  a  | 22 |  2 
5 |  a  | 23 |  3 
6 |  b  | 24 |  3 
7 |  c  | 25 |  3 

Tableau 2

ID | T2Value 
---------------- 
10 |  H 
11 |  J 
12 |  K 
22 |  H 
23 |  H 
24 |  J 
25 |  K 

J'ai trouvé quelques modèles de clone SQL qui me permettent de cloner des données de puits dans la même table ... mais que je commence à traiter les données de clonage dans deux tableaux en même temps, puis relier les nouvelles lignes correctement ... ce n'est pas quelque chose que je sens que j'ai une bonne compréhension de.

J'ai pensé que je pourrais faire des auto-jointures pour faire face à cela, mais je suis inquiet dans les cas où les champs non-clés ont les mêmes données dans plusieurs rangées.

+1

Pourquoi la table 2 n'a-t-elle que 7 enregistrements après la deuxième étape? On dirait qu'il devrait avoir 8? –

+0

@Abe - Les deux tables doivent avoir le même nombre d'enregistrements puisqu'elles sont liées 1-1. Pourquoi avez-vous pensé qu'ils devraient 8? Je ne pense pas que je néglige quelque chose, mais mon esprit est bouché après une matinée d'écriture de pages de SQL. – AmoebaMan17

+0

BTW - Notez la colonne GroupID dans la table 1. Je veux seulement cloner les enregistrements qui font partie du même GroupID. Donc, mon exemple est de cloner uniquement les enregistrements qui sont dans GroupID 1. – AmoebaMan17

Répondre

1

Est-ce que ma seule option est d'utiliser un curseur pour suivre le mappage d'ID? Voici un pseudo-code que j'ai écrit ... pas encore testé. J'espérais quelque chose de plus concis. Est-ce ma seule option?

DECLARE @NewT2Key INT 
DECLARE @OldT2Key INT 
DECLARE @T2Value VARCHAR(50) 
DECLARE @T2KeyNewOld TABLE (OldT2Key INT, NewT2Key INT) 

DECLARE @NewGroupID INT 
DECLARE @OldGroupID INT 

SET @NewGroupID = 3 
SET @OldGroupID = 1 

-- 
-- STEP 1: CLONE THE TABLE2 DATA AND KEEP MAPPING OF OLD-to-NEW IDs 
-- 
DECLARE curT2Keys 
CURSOR FAST_FORWARD LOCAL FOR 
    SELECT t2.ID, 
     t2.T2Value 
    FROM dbo.Table2 t2 
     JOIN dbo.Table1 t1 
     ON t2.ID = t1.T2ID 
    WHERE t1.GroupID = @OldGroupID 
    ORDER BY t1.ID 

OPEN curT2Keys 
FETCH NEXT FROM curT2Keys INTO @OldT2Key, @T2Value 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @NewT2Key = (SELECT MAX(ID)+1 FROM dbo.Table2) 

    INSERT INTO dbo.Table2(ID, T2Value) 
    VALUES(@NewT2Key, @T2Value) 

    INSERT INTO @T2KeyNewOld(OldT2Key, NewT2Key) 
    VALUES(@OldT2Key, @NewT2Key) 

    FETCH NEXT FROM curT2Keys INTO @OldT2Key, @T2Value 
END 
CLOSE curT2Keys 
DEALLOCATE curT2Keys 

-- 
-- STEP 2: CLONE THE TABLE1 DATA AND UPDATE IDs WITH NEW MAPPING 
-- 

     INSERT INTO dbo.Table1([ID], [T1Value], [T2ID], [GroupID]) 
     (SELECT 
      (SELECT MAX(ID) FROM dbo.Table1) + ROW_NUMBER() OVER (ORDER BY GroupID), 
      t1.[T1Value], 
      t2.[NewT2Key], 
      @NewGroupID 
     FROM dbo.Table1 t1 
      JOIN @T2KeyNewOld t2 
      ON t1.T2ID = t2.OldT2Key 
     WHERE t1.GroupID = @OldGroupID 
    ) 
+0

Je viens de tester le code ci-dessus, et il a semblé fonctionner pour moi. Je me sens toujours comme quand j'opte pour utiliser des boucles WHILE dans mon TSQL, je pense comme un programmeur et pas comme un DBA. Je suis au moins capable de faire une table JOINS à l'ÉTAPE 2. J'aimerais juste savoir comment créer une Table Temporaire pour mes mappings sans avoir à utiliser le Cursor. – AmoebaMan17

Questions connexes