2010-02-10 11 views
5

Używam SQL Server 2005.wstawić dane z jednej tabeli do wielu tabelach

Jestem migracji danych w bieżącej bazie danych z jednej tabeli() do nowej bazy danych (znormalizowane - wiele tabelach). W nowej bazie danych mam tabelę podstawową (nazwijmy ją "BaseTable") i wiele innych tabel (nazwijmy je: "DependentA" i "DependentB"). Niektóre dane ze starej bazy danych trafią do BaseTable, a niektóre trafią do pozostałych dwóch. BaseTable ma relację jeden-do-jednego z DependentA i DependentB, używając Id jako klucza obcego.

Oto moje pytanie. Jak mam przeprowadzić migrację danych? Oto zapytanie, które próbowałem, które działa z jednym wyjątkiem: klucze obce w tabeli BaseTable dla pozostałych dwóch są identyczne, zamiast tego lub mające inną.

Begin SQL: 

BEGIN TRANSACTION 

DECLARE @dep1Id int 

DECLARE @dep2Id int 

INSERT INTO DependentA (column1, column2) 
SELECT c1, c2 
FROM OldDatabase.OldTable 
SELECT @dep1Id = Scope_Identity() 

INSERT INTO DependentB (column3, column4) 
SELECT c3, c4 
FROM OldDatabase.OldTable 
SELECT @dep2Id = Scope_Identity() 

INSERT INTO BaseTable (column5, dependentTable1Id, dependentTablr2Id) 
SELECT c5, @dep1Id, @dep2Id 
FROM OldDatabase.OldTable 

COMMIT 
+0

Wykonaj jedną z kolumn w tabelach zależnych posiadają unikalne wartości, które mogłyby być sprawdzonym? (tj. c1 i c3) – CAbbott

+0

W tych tabelach znajduje się klucz podstawowy (DependentA i DependentB). – jchapa

Odpowiedz

7

Problemem jest to, że @ dep1Id i @ dep1Id są skalarne i zachowując ostatnią wartość tylko z dwoma wkładkami ustalane na podstawie.

ponieważ jest to jednorazowe powinieneś zrobić to jako kursora

DECLARE CURSOR @curs FOR 
SELECT c1,c2,c3,c4,c5 FROM OldDatebase 

open @curs 
fetch next from @curs into 
@c1,@c2,@c3,@c4,@c5 --declare these! 

while @@fetch_status <> 0 
BEGIN 

INSERT INTO DependentA (column1, column2) VALUES @c1, @c2 

SELECT @dep1Id = Scope_Identity() 

INSERT INTO DependentB (column3, column4) VALUES @c3, @c4 

SELECT @dep2Id = Scope_Identity() 

INSERT INTO BaseTable (column5, department1Id, department2Id) @c5, @dep1Id, @dep2Id  

fetch next from @curs into 
@c1,@c2,@c3,@c4,@c5 
END 
close @curs 
deallocate @curs 

Moja składnia kursor jest prawdopodobnie usiane błędami, ale masz pomysł.

+0

Zadziałało. Dzięki za tonę! To zamyka 8-godzinny projekt. ;) – jchapa

+0

kursor nie jest możliwe dla dużych zbiorów danych nawet najgorsze dla mnie z 261000 wierszy – Shahdat

4

Aby uniknąć kursora dla dużych zestawów danych, tymczasowo włącz OldTable_id do nowych tabel.

BEGIN TRANSACTION 

INSERT INTO DependentA (OldTable_id, column1, column2) 
SELECT ot.id, ot.c1, ot.c2 
FROM OldDatabase.OldTable ot 

INSERT INTO BaseTable (OldTable_id, column5) 
SELECT ot.id, ot.c5 
FROM OldDatabase.OldTable ot 

UPDATE BaseTable 
    SET BaseTable.dependentTable1_id = DependentA.id 
    FROM BaseTable 
    INNER JOIN DependentA on DependentA.OldTable_id = BaseTable.OldTable_id 

COMMIT 

Wykonaj to samo dla tabeli DependentB i innych tabel znormalizowanych z OldTable.

Usuń OldTable_id po migracji danych.

1

[podaj opis obrazu tutaj] [1] ZeorOne jest głównym stołem, z którego chcesz pobrać dane i wstawić je odpowiednio do zera i jednego stołu.

select idzero,namezero,idone,nameone from zeroone 

insert into zero 
select idzero,namezero from zeroone 

insert into one 
select idone,nameone from zeroone 

lub chcesz używać kursora wstawić dane z wybranych kolumn z Zeroone w dwóch tabelach zapytań jest tutaj

Declare @idzero int 
Declare @namezero varchar(50) 
Declare @idone int 
Declare @nameone varchar(50) 

Declare Cur Cursor for 
select idzero,namezero,idone,nameone from zeroone 

open Cur 

fetch Cur into @idzero,@namezero,@idone,@nameone 

While @@fetch_status = 0 
begin 

    insert into zero 
    select @idzero,@namezero 

    insert into one 
    select @idone,@nameone 

    fetch Cur into @idzero,@namezero,@idone,@nameone 

end 

close Cur 
Deallocate Cur 
+0

Nie jestem pewien, że ta odpowiedź, do 7-letniego postu dodaje wiele wartości do wątku ... – Wndrr