2012-02-22 7 views
5

voglio per creare una stampa che metterà a confronto due tabelle e inserire i valori non corrispondenti in un'altra terza tabella o tabella delle variabili qualcosa di simile:SQL Merge con l'inserimento nell'altro tavolo

MERGE Assets AS target 
USING (@id, @name)FROM Sales AS source (id, name) ON (target.id = SOURCE.id) 
WHEN MATCHED THEN 
    UPDATE SET target.Status = @status, target.DateModified = SYSUTCDATETIME() 
WHEN NOT MATCHED THEN 
    INSERT INTO @tableVar (id, name, status, dateModified) 
    VALUES (@id, @name, @status, SYSUTCDATETIME()) 

VUOI ragazzi aiutare me per trasformarlo usando altri costrutti.

risposta

10

Solo non è possibile fare questo. MERGE funziona solo su due tabelle: sorgente e destinazione.

Per il vostro requisito, è necessario ad es. utilizzare un CTE (Common Table Expression) per trovare le righe che non corrispondono e inserirle nella terza tabella.

Qualcosa di simile:

;WITH NonMatchedData AS 
(
    -- adapt this as needed - just determine which rows match your criteria, 
    -- and make sure to return all the columns necessary for the subsequent INSERT 
    SELECT (columns) 
    FROM dbo.SourceTable 
    WHERE ID NOT IN (SELECT DISTINCT ID FROM dbo.TargetTable) 
) 
INSERT INTO dbo.ThirdTable(Col1, Col2, ....., ColN) 
    SELECT Col1, Col2, ....., ColN 
    FROM NonMatchedData 
+1

Esiste un'alternativa a "NOT IN" in questo caso? Qualcosa come un "JOIN" che riattribuisce tutte le righe che non sono riuscite a "UNIRE"? Altro quindi 'SINISTRA JOIN' +' IS NULL'. Inoltre, il CTE è davvero necessario? Non può 'INSERIRE IN ThirdTable FROM SELECT NonMatchedData'? – Alexandre

+1

@PeekaySwitch: certo - ma poi ** STAI ** facendo un 'LEFT OUTER JOIN' e controllando che una colonna dal' dbo.TargetTable' sia 'NULL' .... Non vedo quale altra opzione sarebbe sii lì, davvero .... –

+1

Sai in cima alla tua testa cosa offre prestazioni migliori? Mi aspetto che il 'LEFT OUTER JOIN' sia più efficace, ma forse sono vicini, ho sempre cercato di evitare di usare' NOT IN' con enormi quantità di dati in 'Where' (come ID) – Alexandre

2

È possibile farlo molto facilmente ...

Puoi avvolgere l'istruzione MERGE entro un INSERT INTO FROM:
http://technet.microsoft.com/en-us/library/bb510625.aspx#sectionToggle2

OPPURE

È possibile farlo direttamente all'interno dell'istruzione di unione:

esempio rapida:

WHEN NOT MATCHED THEN 
    DELETE 
OUTPUT Deleted.* INTO dbo.MyTable; 

Questo inserirà i non-match nella vostra tabella di destinazione esistente. Puoi utilizzare le tabelle v aggiornate, inserite, eliminate per indirizzare i dati ad altri luoghi.

+0

Questo deve essere in una clausola 'MATCHED' o' NOT MATCHED BY SOURCE', ma fa il trucco. –