The MERGE statement scans a table and either INSERTs, UPDATEs, or DELETEs rows depending on whether the rows satisfy a specified condition.
MERGE INTO targetTable [ [ AS ] targetCorrelationName ] USING sourceTable [ [ AS ] sourceCorrelationName ] ON searchCondition mergeWhenClause [ mergeWhenClause ]*
Both targetTable and sourceTable are tableNames.
targetTable must identify a base table. targetTable may not be a transition table in a triggered statement, and it may not be a synonym.
sourceTable must identify a base table or a table function, and it may not be a synonym.
Both targetCorrelationName and sourceCorrelationName are correlationNames.
The unqualified source table name (or its correlation name) may not be the same as the unqualified target table name (or its correlation name).
The searchCondition is a Boolean expression. Columns referenced by the searchCondition must be in either targetTable or sourceTable. Functions mentioned in the searchCondition may not modify SQL data.
The row count for a successful MERGE statement is the total number of rows inserted, updated, and deleted by the statement.
WHEN MATCHED [ AND matchRefinement ] THEN { mergeUpdate | DELETE }
The matchRefinement is a Boolean expression. Columns referenced by the matchRefinement must be in either targetTable or sourceTable. Functions mentioned in the matchRefinement may not modify SQL data.
WHEN NOT MATCHED [ AND matchRefinement ] THEN mergeInsert
The matchRefinement is a Boolean expression. Columns referenced by the matchRefinement must be in either targetTable or sourceTable. Functions mentioned in the matchRefinement may not modify SQL data.
Although permitted to do so by the SQL Standard, Derby does not currently support subqueries in WHEN [ NOT ] MATCHED clauses.
UPDATE SET column-Name = value [, column-Name = value ]*
Columns updated must be columns in targetTable.
Functions mentioned in the UPDATE values may not modify SQL data.
On the right side of SET operators for UPDATE actions, DEFAULT is the only value allowed for generated and identity columns.
No list of updated columns may mention the same column more than once.
The data types of updated values must be assignable to the corresponding columns according to the rules documented in Data type assignments and comparison, sorting, and ordering.
INSERT [ ( Simple-column-Name [ , Simple-column-Name ]* ) ] VALUES ( value [, value ]* )
Columns inserted must be columns in targetTable.
Functions mentioned in the INSERT values may not modify SQL data.
No list of inserted columns may mention identity columns, or may mention the same column more than once.
In a VALUES clause, DEFAULT is the only allowed value for generated columns.
The data types of inserted values must be assignable to the corresponding columns according to the rules documented in Data type assignments and comparison, sorting, and ordering.
The user who executes a MERGE statement must have the following privileges. See GRANT statement for information on privileges.
The MERGE statement behaves as described in the following table.
Situation or Behavior | Description |
---|---|
Source table is empty | If the sourceTable is empty, a "no data" warning is raised with SQLState 02000. |
An initial join is performed | Before any changes are made to targetTable, the sourceTable is joined to the targetTable by means of the ON clause. Call this join result J. Let N denote the rows in sourceTable missing from this join. |
Clause order is important | The mergeWhenMatched and mergeWhenNotMatched clauses are applied in declaration order. |
The first matched clause wins | For each row in J, Derby applies only the first mergeWhenMatched clause whose matchRefinement is satisfied. |
The first not matched clause wins | For each row in N, Derby applies only the first mergeWhenNotMatched clause whose matchRefinement is satisfied. |
Double dipping is not permitted | A cardinality violation is raised if a MERGE statement attempts to change (update or delete) the same row twice. This condition can occur if more than one source row joins to the same target row. |
MERGE INTO hotIssues h USING issues i ON h.issueID = i.issueID WHEN MATCHED AND i.lastUpdated = CURRENT_DATE THEN UPDATE SET h.lastUpdated = i.lastUpdated WHEN MATCHED AND i.lastUpdated < CURRENT_DATE THEN DELETE WHEN NOT MATCHED AND i.lastUpdated = CURRENT_DATE THEN INSERT VALUES ( i.issueID, i.lastUpdated ); MERGE INTO companies c USING adhocInvoices a ON a.companyName = c.companyName WHEN NOT MATCHED THEN INSERT ( companyName ) VALUES ( a.companyName ); MERGE INTO warehouse.productList w USING production.productList p ON w.productID = p.productID WHEN MATCHED and w.lastUpdated != p.lastUpdated THEN UPDATE SET lastUpdated = p.lastUpdated, description = p.description, price = p.price WHEN NOT MATCHED THEN INSERT values ( p.productID, p.lastUpdated, p.description, p.price );