2011-02-01 11 views
10

Sto cercando una spiegazione chiara di ciò che la dichiarazione MERGE in Oracle fa davvero.Qualcuno potrebbe spiegare cosa fa realmente la dichiarazione MERGE in Oracle?

Ecco quello che sono dopo:

MERGE INTO (target_table) t 
USING (source_view) s 
    ON (join condition) 
WHEN MATCHED THEN UPDATE SET col1 = val1 [, ...] 
WHEN NOT MATCHED THEN INSERT (col1 [, ...]) VALUES (val1 [, ...]) 
  • che tipo di join viene eseguita? Penso che sia il join esterno completo, ho ragione?
  • riferimento alla parte WHEN MATCHED: cosa succede quando una riga da t corrisponde a più righe da s?
  • riferimento alla WHEN NOT MATCHED parte ritengo significa “quando una riga di s ha alcuna corrispondenza t”. Ho ragione?

Grazie.

risposta

11

che tipo di join viene eseguita? I penso che sia un join esterno completo, sono giusto?

No, è un normale join esterno. La query deve sapere quando ci sono delle righe nella tabella di destinazione che si trovano anche nella tabella di origine e quando nella tabella di origine ci sono dei record che non si trovano nella tabella di destinazione. Poiché la query non deve rispondere alle righe presenti nella tabella di destinazione ma non nella tabella di origine, non è necessario che il join esterno effettui entrambe le operazioni.

Tuttavia, l'outer join non verrà eseguita se non c'è not matched la clausola (che è perfettamente valido). L'ottimizzatore è abbastanza intelligente da sapere che in quel caso è sufficiente un join interno.

riferimento alla parte QUANDO MATCHED: cosa succede quando una riga da t corrisponde file multiple da s?

In caso di più corrispondenze, l'aggiornamento viene eseguito per ciascuna corrispondenza. Ciò significa che qualunque aggiornamento verrà per ultimo sarà quello scritto nel commit. Non c'è modo di dettare un ordine, quindi in questo caso la fonte dell'aggiornamento è effettivamente casuale (dall'insieme delle partite).

Come @ Vincent Malgrat sottolineato, questo non era corretta. Sembra che Oracle produrrà un errore "ORA-40926: impossibile ottenere un set stabile di righe nella tabella sorgente" se ci sono più corrispondenze.

riferimento alla QUANDO NON MATCHED parte I credere significa “quando una riga di s ha nessuna corrispondenza in t”. Ho ragione?

Questo è corretto.

+0

Grazie, questo è esattamente quello che volevo sapere. Suppongo che * regular outer join 'significhi 't right join s' e non' t left join s'? – Benoit

+1

Per quanto riguarda le corrispondenze multiple, il documento specifica menziona che [MERGE è un'affermazione deterministica. Cioè, non puoi aggiornare la stessa riga della tabella di destinazione più volte nella stessa dichiarazione MERGE] (http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_9016.htm#i2081218) . Quando l'aggiornamento è ambiguo, Oracle solleverà un ORA-30926 per precauzione –

+0

@Benoit: è corretto. Se tu stessi scrivendo una query simile, dovresti usare 'right join' o' left join', dal punto di vista dell'ottimizzatore, o è un 'hash join outer' (tipicamente). – Allan

Problemi correlati