MERGE
MERGE#
Syntax#
merge ::=#
merge_operation_spec ::=#
matched_update_clause ::=#
not_matched_insert_clause ::=#
no_rows_insert_clause ::=#
Prerequisites#
In order to use the MERGE clause, the user must have the INSERT and UPDATE object privilege on the target table and the SELECT object privilege on the source table.
Description#
The MERGE statement selects data from the source table and updates or inserts it into the target table. The table specified in the INTO clause is the target table and the table or view specified in the USING clause is the source table. With the ON clause, a condition to evaluate whether the target table is to be updated or inserted into can be specified.
One MERGE statement can substitute multiple executions of DML statements such as INSERT, UPDATE, etc.
hints#
The hint can only be specified after the MERGE keyword. The specified hint applies to INSERT or UPDATE statements.
INTO clause#
This clause specifies the target table to be updated or inserted. Only tables are valid in the INTO clause; views cannot be included.
USING clause#
This specifies data and INTO clause table. Table names, SELECT statements, or views can be used.
ON clause#
INTO clause specifies the condition of the data to change or insert in the table. Depending on the condition of the ON clause, the same record can be changed many times or the same record can be inserted many times.
After the ON clause, three clauses can be used: matched_update_clause, not_matched_insert_clause, and no_rows_insert_clause. Each clause can be specified once and in any order.
matched_update_clause#
If there is data that satisfies the condition of the ON clause, the UPDATE statement that changes the record is written. The table to be changed is omitted because it is specified in the INTO clause.
Restriction:#
A column referenced in the ON condition clause cannot be updated.
not_matched_insert_clause#
This clause specifies the insertion of columns into the target table when the row satisfying the condition of the ON clause does not exist in the target table. To omit the column list following the INSERT keyword, , the number of columns in the target table must equal the number of values in the VALUES clause.
no_rows_insert_clause#
This clause specifies the value to be inserted into the column of the target table when the row satisfying the condition of the ON clause does not exist in the source table. To omit the column list following the INSERT keyword, the number of columns in the target table must equal the number of values in the VALUES clause.
Examples#
<Query> This example inserts or changes data in the TEST_MERGE table according to the condition.
The record that satisfies the condition of the ON clause in the TEST_MERGE table is changed to data in the USING clause, and a new record is inserted if it is not satisfied.
As in the condition of the ON clause, if there is a record with the same EMPNO column value by comparing the data of the TEST_MERGE table in the INTO clause with the USING clause, the LASTNAME column value of the record in the INTO clause TEST_MERGE table is changed. If there is no record with the same EMPNO column value, insert the data from the USING clause into the TEST_MERGE table as a new record.
CREATE TABLE TEST_MERGE (EMPNO INT, LASTNAME CHAR(20));
INSERT INTO TEST_MERGE VALUES(1, 'KIM');
INSERT INTO TEST_MERGE VALUES(2, 'LEE');
INSERT INTO TEST_MERGE VALUES(5, 'PARK');
INSERT INTO TEST_MERGE VALUES(4, 'CHOI');
INSERT INTO TEST_MERGE VALUES(7, 'YUN');
iSQL> SELECT * FROM TEST_MERGE WHERE EMPNO IN (1, 7, 9);
EMPNO LASTNAME
-----------------------------------------------
1 KIM
7 YUN
2 rows selected.
iSQL> MERGE INTO TEST_MERGE OLD_T
USING
(
SELECT 1 EMPNO, 'KANG' LASTNAME FROM DUAL UNION ALL
SELECT 7 EMPNO, 'SON' LASTNAME FROM DUAL UNION ALL
SELECT 9 EMPNO, 'CHEON' LASTNAME FROM DUAL
) NEW_T
ON OLD_T.EMPNO = NEW_T.EMPNO
WHEN MATCHED THEN
UPDATE SET OLD_T.LASTNAME = NEW_T.LASTNAME
WHEN NOT MATCHED THEN
INSERT (OLD_T.EMPNO, OLD_T.LASTNAME) VALUES(NEW_T.EMPNO, NEW_T.LASTNAME);
3 rows merged.
iSQL> SELECT * FROM TEST_MERGE WHERE EMPNO IN (1, 7, 9);
EMPNO LASTNAME
-----------------------------------------------
1 KANG
7 SON
9 CHEON
3 rows selected.
<Query> The following example shows how to change the same record repeatedly due to misuse of the ON clause.
DROP TABLE TEST_MERGE;
CREATE TABLE TEST_MERGE (EMPNO INT, LASTNAME CHAR(20));
INSERT INTO TEST_MERGE VALUES(1, 'KIM');
INSERT INTO TEST_MERGE VALUES(2, 'LEE');
INSERT INTO TEST_MERGE VALUES(5, 'PARK');
INSERT INTO TEST_MERGE VALUES(4, 'CHOI');
INSERT INTO TEST_MERGE VALUES(7, 'YUN');
DROP TABLE TEST_MERGE2;
CREATE TABLE TEST_MERGE2 (EMPNO INT, LASTNAME CHAR(20));
INSERT INTO TEST_MERGE2 VALUES(8, 'JANG');
INSERT INTO TEST_MERGE2 VALUES(1, 'KIM');
INSERT INTO TEST_MERGE2 VALUES(7, 'YUN');
iSQL> SELECT * FROM TEST_MERGE;
EMPNO LASTNAME
-------------------------------------
1 KIM
2 LEE
5 PARK
4 CHOI
7 YUN
5 rows selected.
iSQL> SELECT * FROM TEST_MERGE2;
EMPNO LASTNAME
-------------------------------------
8 JANG
1 KIM
7 YUN
3 rows selected.
iSQL> MERGE INTO TEST_MERGE OLD_T
USING TEST_MERGE2 NEW_T
ON OLD_T.EMPNO = NEW_T.EMPNO OR OLD_T.EMPNO = 8
WHEN MATCHED THEN
UPDATE SET LASTNAME = 'MATCHED'
WHEN NOT MATCHED THEN
INSERT VALUES( EMPNO, 'NOTMATCHED' )
WHEN NO ROWS THEN
INSERT VALUES( 10, 'NO ROWS' );
5 rows merged.
iSQL> SELECT * FROM TEST_MERGE;
EMPNO LASTNAME
-------------------------------------
2 LEE
5 PARK
4 CHOI
1 MATCHED
7 MATCHED
8 MATCHED
6 rows selected.
<Query> The following example executes the WHEN NO ROWS THEN clause.
DROP TABLE TEST_MERGE;
CREATE TABLE TEST_MERGE (EMPNO INT, LASTNAME CHAR(20));
INSERT INTO TEST_MERGE VALUES(1, 'KIM');
INSERT INTO TEST_MERGE VALUES(2, 'LEE');
INSERT INTO TEST_MERGE VALUES(5, 'PARK');
INSERT INTO TEST_MERGE VALUES(4, 'CHOI');
INSERT INTO TEST_MERGE VALUES(7, 'YUN');
DROP TABLE TEST_MERGE2;
CREATE TABLE TEST_MERGE2 (EMPNO INT, LASTNAME CHAR(20));
iSQL> SELECT * FROM TEST_MERGE;
EMPNO LASTNAME
-------------------------------------
1 KIM
2 LEE
5 PARK
4 CHOI
7 YUN
5 rows selected.
MERGE INTO TEST_MERGE OLD_T
USING TEST_MERGE2 NEW_T
ON NEW_T.EMPNO = OLD_T.EMPNO AND NEW_T.EMPNO = 10
WHEN MATCHED THEN
UPDATE SET LASTNAME = 'MATCHED'
WHEN NOT MATCHED THEN
INSERT VALUES( 10, 'NOTMATCHED' )
WHEN NO ROWS THEN
INSERT VALUES( 10, 'NO ROWS' ) ;
1 row merged.
iSQL> SELECT * FROM TEST_MERGE;
EMPNO LASTNAME
-----------------------------------------------
1 KIM
2 LEE
5 PARK
4 CHOI
7 YUN
10 NO ROWS
6 rows selected