Switch to: V12V11V10V9V8V7V6V5

Table of Contents

MERGE

Syntax

merge_statement
    : MERGE [INTO] table_name [[AS] table_alias]
        USING table_name [[AS] table_alias]
        join_specification
        merge_operation_spec

merge_operation_spec
    :	{ merge_when_clause }+

merge_when_clause
    :    WHEN MATCHED THEN merge_matched
    |    WHEN NOT MATCHED
         { BY SOURCE THEN merge_matched
         | [BY TARGET] THEN merge_not_matched
         }

// This is simplified form of UPDATE. There is no tbl_name and WHERE clause.
merge_matched
    :    UPDATE SET set_clause_list
    |    DELETE

// This is simplified form of INSERT. It inserts only one row.
merge_not_matched
    :    INSERT [ ( column_name_list ) ]
    {    DEFAULT VALUES
    |	 VALUES ( values_list )
    }  

Description

The MERGE statement is a very powerful feature. In general, it is for merging two tables' data. But there are few nuances, which allow using MERGE in the wide range of scenarios.

There are always:

  • two tables - source and target (self-merge is also possible);
  • predicate to join that tables;
  • one or more action(s).

Valentina joins the tables internally and then, iterates the join result firing appropriate actions for each join-result row.

There are only 3 possible “merge actions” (at least for now):

  • WHEN MATCHED. Fired when there is a record in target table for current source table's record. It could be “UPDATE” or “DELETE” statements only;
  • WHEN NOT MATCHED [ BY TARGET ]. Fired when there is no record in target table for current source table's record. It could be “INSERT” statement only;
  • WHEN NOT MATCHED BY SOURCE. Fired when there is no record in source table for current target table's record.

It could be “UPDATE” or “DELETE” statements only;

Important note - “statement triggers” will be ignored for “INSERT”, “DELETE” and “UPDATE” actions since there is MERGE statement, which can fire up a bunch of different actions.

Examples

Insert or update (in case of duplicate) records but for some set of records only:

MERGE t1 AS Target
USING t2 AS SOURCE
ON (Target.ID = SOURCE.ID AND SOURCE.f1 > 100 ) 
WHEN NOT MATCHED BY TARGET
    THEN INSERT(ID, f1) VALUES( S.id, S.f1 )
WHEN MATCHED 
    THEN UPDATE SET T.f1 = S.f1

Update subset of linked records:

MERGE t1
USING t2
ON (t1.ID = t2.ptr AND t2.f2 > 100 ) 
WHEN MATCHED 
    THEN UPDATE SET t1.f1 = t2.f2

Delete all not-linked records:

MERGE INTO t_merge_target
USING t_merge_source
ON id = ptr
WHEN NOT MATCHED BY SOURCE THEN 
DELETE