Ciao a tutti,
parliamo un attimo degli aggiornamenti e delle cancellazioni nelle tabelle!
Sembra del tutto normale scrivereÂ
DELETE FROM [Tabella] WHERE [Campo] = [Valore]
oppure
UPDATE [Tabella] SET [Campo] = [Valore] WHERE [Campo] = [Valore]
ma se dovessimo cancellare o aggiornare i dati di una tabella in base ai valori di un’altra come facciamo?
Potremmo scrivere delle query con 7 SELECT nidificate e 7 condizioni di esistenza, ma oltre a diventare matti per scriverle e stare attenti a non distruggere i dati, il DB impiegherebbe un sacco di tempo ad eseguirle…beh…ci viene in aiuto l’istruzione MERGE.
Con questa istruzione infatti possiamo aggiornare, inserire o cancellare i dati in una tabella facendola “matchare” (passatemi il termine) con un’altra, oppure con una SELECT ad hoc per restituire solo i dati che effettivamente ci servono.
Passiamo alla pratica.
Creiamo una tabella di prova
CREATE TABLE test1 AS
SELECT object_id, status
FROMÂ Â all_objects
WHEREÂ 1=2;
Possiamo inserire dati se non esistono nella tabella (WHEN NOT MATCHED)
MERGE INTO test1 a
USING all_objects b
ON (a.object_id = b.object_id)
WHEN NOT MATCHED THEN
 INSERT (object_id, status)
 VALUES (b.object_id, b.status);
Possiamo aggiornare SOLO i dati che già esistono nella tabella (WHEN MATCHED)
MERGE INTO test1 a
USING all_objects b
ON (a.object_id = b.object_id)
WHEN MATCHED THEN
 UPDATE SET a.status = b.status;
Possiamo inserire ed aggiornare i dati con una sola query
MERGE INTO test1 a
USING all_objects b
ON (a.object_id = b.object_id)
WHEN MATCHED THEN
UPDATE SET a.status = b.status
WHEN NOT MATCHED THEN
 INSERT (object_id, status)
 VALUES (b.object_id, b.status);
Potremmo anche condizione le INSERT e gli UPDATE (WHERE)
MERGE INTO test1 a
USING all_objects b
ON (a.object_id = b.object_id)
WHEN MATCHED THEN
 UPDATE SET a.status = b.status
 WHERE b.status != 'VALID'
WHEN NOT MATCHED THEN
 INSERT (object_id, status)
 VALUES (b.object_id, b.status)
 WHERE b.status != 'VALID';
Ovviamente si può utilizzare anche il comando DELETE
MERGE INTO test1 a
USING all_objects b
ON (a.object_id = b.object_id)
WHEN MATCHED THEN
 UPDATE SET a.status = b.status
 WHERE b.status != 'VALID'
DELETE WHERE (b.status = 'VALID');
Se poi non volessimo utilizzare la MERGE potremmo fare anche così per UPDATE o DELETE in più di una tabella
DELETE FROM (SELECT 'x' FROM dept d, emp e
WHERE d.deptno = e.deptno
AND loc = 'CHICAGO');
oppure
UPDATE (SELECT e.sal, d.deptno
       FROM emp e, dept d
       WHERE d.deptno = e.deptno
       AND  loc = 'CHICAGO') x
SET x.sal = x.sal + 1
Alla prossima