2013-08-09 12 views
5

Potrzebuję scalić dane z tabeli dawców w dwóch tabelach docelowych. Struktura jest jak poniżej. Jeśli projid nie zostanie znaleziony w tabeli śledzenia, muszę utworzyć nowy komponent w tabeli komponentów i użyć nowego identyfikatora do wstawienia do tabeli śledzenia. W przypadku elementów, których nie ma już w tabeli dawcy, kolumna "aktywna" tabeli śledzenia powinna być oznaczona jako 0. Czy mogę to osiągnąć w pojedynczej instrukcji łączenia?Scal dane w dwóch tabelach docelowych

dawcy Tabela

projid  | datestamp | Ownerid 
------------------------------------------------- 
c_abc  1-jan-2013  name1 
c_def  2-jan-2013  name3 
c_ghi  3-jan-2013  name4 

tabeli ślad

compid  |projid  |active | ... 
----------------------------------------------- 
123   c_abc  1 
124   c_xyz  1 
125   c_def  1 

tabeli składników

compid  |ownerid 
------------------------- 
123  name1 
124  name2 
125  name3 

WYJŚCIA TABELE PO Merge:

stół komponent

compid  |ownerid 
------------------------- 
123  name1 
124  name2 
125  name3 
126  name4 

stół ślad

compid  |projid  |active | ... 
----------------------------------------------- 
123   c_abc  1 
124   c_xyz  0 
125   c_def  1 
126   c_ghi  1 
+0

Skąd się wzięło to "imię4"? –

+0

name4 pochodzi ze stołu dawcy, a także – mhn

+0

@mhn - czy mówisz, że jest inna kolumna w tabeli Dawcy, która zawiera ten tekst? Jeśli tak, czy możesz dodać go do swojego przykładu? –

Odpowiedz

5

Teoretycznie nie powinno być rozwiązanie to zrobić w jednej instrukcji, ale mam do tej pory nie udało się go znaleźć. *

Oto jak można to zrobić z dwóch MERGE stwierdzeń:

WITH CTE_trgt AS 
(
    SELECT c.compid, c.ownerid, t.projid, t.active 
    FROM component c 
    INNER JOIN trace t ON c.compid = t.compid 
) 
MERGE CTE_trgt t 
USING Donor s 
ON t.projid = s.projid 
WHEN NOT MATCHED BY TARGET 
    THEN INSERT (ownerid) 
    VALUES (s.ownerid) 
OUTPUT 
    INSERTED.compid, s.projid, 1 INTO trace; 


MERGE trace t 
USING Donor s 
ON t.projid = s.projid 
WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0; 

SQLFiddle DEMO


* Część z aktualizacją Aktywna kolumna:

WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0 

powinien być w stanie zmieścić się w górnej zapytania tworzącego single merge statement dla wszystkich operacji, ale zgłasza błąd:

View or function 't' is not updatable because the modification affects multiple base tables

nawet jeśli jest to oczywiście pojedyncza kolumna, a regular non-merge update works fine. Może ktoś zna przyczynę i/lub obejście tego problemu.

+0

Cześć Nenad, wielkie dzięki za twoje wkłady !! pierwsze oświadczenie scalające poszło dobrze. Ale instrukcja, która aktualizuje flagę aktywną w tabeli śledzenia, nie jest w stanie dostosować tak, jak chcę. Tęskniłem za kolejną dawką donoridu w śladzie. Więc muszę zaktualizować tylko te wiersze, w których dawca = "MójDonorId". Nie jestem w stanie spełnić tej klauzuli gdziekolwiek na wyciągu scalającym. próbowałem – mhn

+0

... MERGE (wybierz * z trace gdzie donorid = 'MyDonorId') t USING Darczyńców ON t.projid = s.projid KIEDY NIE DOPASOWANO ŹRÓDŁEM THEN UPDATE SET t.active = 0; Mówi zła składnia :( – mhn

+0

@ mhn Możesz użyć wspólnego wyrażenia tabelowego - składnia 'WITH CTE', podobnie jak w pierwszej instrukcji do filtrowania twojego celu –