SQL: INSERT o UPDATE in automatico
Come far decidere direttamente allo script SQL se fare una INSERT o una UPDATE.
Quante volte vi sarà capitato di dover aggiornare una tabella con dei dati provenienti da una fonte esterna? Nella maggioranza dei casi, i dati da importare possono sia essere nuovi rispetto alla vostra tabella che essere degli aggiornamenti.
Scorrere con un cursore la tabella da importare e vedere record per record se è una novità o un aggiornamento è una scelta poco efficiente. Quale può essere allora una soluzione più performante?
Sfruttare la JOIN
La domanda necessaria da farsi è questa: in base a quale chiave riesco a capire se un record è una novità o un aggiornamento?
Una volta trovata la risposta, il meccanismo è semplice:
- si metteranno in JOIN le due tabelle (da importare ed esistente) relazionandole proprio con la chiave individuata
- la JOIN sarà una LEFT JOIN, con a sinistra la tabella da importare, e a destra quella già esistente
- come noto, la LEFT JOIN restituirà una serie di colonne NULL nella tabella di destra nel caso non ci siano corrispondenze: sfruttando questa caratteristica potremo quindi individuare quali sono i record già esistenti e quali invece sono nuovi
- ovviamente quelli nuovi saranno quelli con contenuto NULL, che sta a significare che i record della tabella di sinistra (da importare) NON sono già esistenti nella tabella di destra (esistente) e vanno quindi inseriti
- quelli invece non-NULL sono già esistenti, e quindi andranno aggiornati
- attenzione ad eseguire PRIMA la UPDATE e poi la INSERT; in caso contrario verranno aggiornati anche i record appena inseriti: i dati non vengono assolutamente danneggiati, ma sicuramente ci sarà una perdita di tempo
Esempio pratico
Un esempio aiuterà a comprendere più facilmente il meccanismo.
Immaginiamo di dover aggiornare una tabella di Dati Anagrafici con dei dati che ci vengono inviati periodicamente da un corrispondente; in questo caso, la chiave identificativa (univoca) sarà la Partita IVA.
Per comodità, avremo già importato i dati del nostro corrispondente in una tabella temporanea; i nomi delle colonne saranno gli stessi.
Impostiamo quindi la JOIN:
-- TS=TableSource, TT=TableTarget SELECT TS.Descrizione, TS.PartitaIVA, TT.Descrizione, TT.PartitaIVA FROM #tmpAnag TS LEFT JOIN ANAGRAFICHE TT ON TS.PartitaIVA=TT.PartitaIVA
Quando eseguiremo questa query, vederemo elencate delle corrispondenze esatte nel caso di record da aggiornare, mentre invece noteremo TT.Descrizione e TT.PartitaIVA a NULL nel caso di novità.
Sfrutteremo quindi la JOIN di riferimento per impostare prima una UPDATE…FROM…JOIN per fare gli aggiornamenti, poi una INSERT…SELECT…JOIN per fare gli inserimenti.
UPDATE
-- TS=TableSource, TT=TableTarget
UPDATE ANAGRAFICHE SET
TT.Denominazione=TS.Denominazione,
TT.Indirizzo=TS.Indirizzo,
TT.CAP=TS.CAP,
TT.Localita=TS.Localita,
TT.PartitaIVA=TS.PartitaIVA
FROM
#tmpAnag TS LEFT JOIN ANAGRAFICHE TT ON TS.PartitaIVA=TT.PartitaIVA
-- fa correttamente la JOIN? Quindi c'è GIA'! ---> UPDATE
INSERT
-- TS=TableSource, TT=TableTarget
INSERT INTO ANAGRAFICHE
(Denominazione,
Indirizzo,
CAP,
Localita,
PartitaIVA)
SELECT
TS.Denominazione,
TS.Indirizzo,
TS.CAP,
TS.Localita,
TS.PartitaIVA
FROM
#tmpAnag TS LEFT JOIN ANAGRAFICHE TT ON TS.PartitaIVA=TT.PartitaIVA
WHERE TT.PartitaIVA IS NULL
-- non fa la JOIN? Quindi NON c'è! ---> INSERT
Inserito nella categoria: SQL
Servono ulteriori informazioni?






Grande!!!! Proprio quello che cercavo!!