DML-оператор MERGE (upsert) в Oracle SQL

Оператор MERGE — DML-оператор вставки (INSERT)/обновления (UPDATE)/удаления (DELETE, начиная с Oracle Database 10g) данных при слиянии таблиц. Kогда вы выполняете оператор MERGE, в сервере Oracle9i Database немедленно сработают триггеры BEFORE UPDATE и BEFORE INSERT (так как в этом операторе предложения WHEN MATCHED THEN UPDATE (когда совпадают, то обновить) и WHEN NOT MATCHED THEN INSERT (когда не совпадают, то вставить) являются обязательными). В сервере Oracle Database 10g будут срабатывать триггеры BEFORE UPDATE, INSERT и/или DELETE – в зависимости от указанных в операторе MERGE операций.

Следующий пример произведет MERGE (слияние) данных из таблицы DEPT_ONLINE в таблицу DEPT:

SQL> SELECT * FROM dept;
 
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        60 HELP DESK      PITTSBURGH
        40 OPERATIONS     BOSTON
 
SQL> SELECT * FROM dept_online;
 
    DEPTNO DNAME          LOC
---------- -------------- -------------
        40 OPERATIONS     BOSTON
        20 RESEARCH DEV   DALLAS
        50 ENGINEERING    WEXFORD
 
 
SQL> MERGE INTO dept d
     USING (SELECT deptno, dname, loc
            FROM dept_online) o
     ON (d.deptno = o.deptno)
     WHEN MATCHED THEN
         UPDATE SET d.dname = o.dname, d.loc = o.loc
     WHEN NOT MATCHED THEN
         INSERT (d.deptno, d.dname, d.loc)
         VALUES (o.deptno, o.dname, o.loc);
 
3 rows merged.
 
 
SQL>  SELECT * FROM dept;
 
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH DEV   DALLAS
        30 SALES          CHICAGO
        50 ENGINEERING    WEXFORD
        60 HELP DESK      PITTSBURGH
        40 OPERATIONS     BOSTON
 
6 rows selected.

Произошло обновление (UPDATE) отдела RESEARCH DEV для DEPTNO = 20, и вставка (INSERT) нового отдел ENGINEERING для DEPTNO = 50. Для отдела OPERATIONS произошло обновление на предыдущее значение :) .

При чем тут UPSERT

UPSERT является сходной операцией обновления существующих в таблице данных и вставке несуществующих, при срабатывании SQL%NOTFOUND в false в данном случае считаем, что update не произошел (операция MERGE появилась в спецификации языка SQL в 2003 году):

 UPDATE  my_table
 SET mast_id = :b1
 WHERE   ...
 IF SQL%NOTFOUND THEN
   INSERT INTO my_table
   VALUES ....
 END IF;

Подробности:

Оставить комментарий