MERGE

The MERGE statement updates a target (a table or view, or the underlying tables or views of a fullselect) using the specified input data. Rows in the target that match the input data are updated as specified, and rows that do not exist in the target are inserted. Updating or inserting a row into a view updates or inserts the row into the tables on which the view is based, if no INSTEAD OF trigger is defined on this view.

Invocation

This statement can be embedded in an application program or issued interactively. It is an executable statement that can be dynamically prepared.

Authorization

The privileges that are held by the privilege set that is defined below must include at least one of the following privileges:

  • SYSADM authority
  • Ownership of the table
  • Start of changeDATAACCESS authorityEnd of change
  • If the search condition contains a reference to a column of the table or view, the SELECT privilege for the referenced table or view
  • If the delete operation is specified, the DELETE privilege for the table or view
  • If the insert operation is specified, the INSERT privilege for the table or view
  • If the update operation is specified, at least one of the following privileges is required:
    • the UPDATE privilege for the table or view
    • the UPDATE privilege on each column that is updated
    • If the right side of the assignment clause contains a reference to a column of the table or view, the SELECT privilege for the referenced table or view

If the database is implicitly created, the database privileges must be on the implicit database or on DSNDB04.

If the insert operation or assignment clause includes a subquery, the privileges that are held by the privilege set must also include at least one of the following privileges:

  • SYSADM authority
  • The SELECT privilege on every table or view that is identified in the subquery
  • Ownership of the tables or views that are identified in the subquery
  • Start of changeDATAACCESS authorityEnd of change

Privilege set: If the statement is embedded in an application program, the privilege set is the privileges that are held by the owner of the plan or package. If the statement is dynamically prepared, the privilege set is determined by the DYNAMICRULES behavior in effect (run, bind, define, or invoke) and is summarized in Table 1. (For more information on these behaviors, including a list of the DYNAMICRULES bind option values that determine them, see Authorization IDs and dynamic SQL.)

Syntax

>>-MERGE INTO--+-table-name-+--+--------------------------+----->
               '-view-name--'  | .-AS-.                   |   
                               '-+----+--correlation-name-'   

>--+---------------------+--USING--| source-values |------------>
   '-| include-columns |-'                             

>--ON--search-condition----------------------------------------->

   .----------------------------------------------------------------.   
   V                                                                |   
>----WHEN--| matching-condition |--THEN--| modification-operation |-+-->

>--+-------------------------------------+---------------------->
   '-NOT ATOMIC CONTINUE ON SQLEXCEPTION-'   

>--+------------------+----------------------------------------><
   '-QUERYNO--integer-'   

include-columns:

Read syntax diagram
               .-,--------------------------.      
               V                            |      
>>-INCLUDE--(----column-name--| data-type |-+--)---------------><

data-type:

Read syntax diagram
>>-+-| built-in-type |-+---------------------------------------><
   '-distinct-type-----'   

built-in-type:

>>-+-+-SMALLINT----+-------------------------------------------------+-><
   | +-+-INTEGER-+-+                                                 |   
   | | '-INT-----' |                                                 |   
   | '-BIGINT------'                                                 |   
   |                  .-(5,0)-------------------.                    |   
   +-+-+-DECIMAL-+-+--+-------------------------+--------------------+   
   | | '-DEC-----' |  |          .-,0-------.   |                    |   
   | '-NUMERIC-----'  '-(integer-+----------+-)-'                    |   
   |                             '-,integer-'                        |   
   |          .-(53)------.                                          |   
   +-+-FLOAT--+-----------+--+---------------------------------------+   
   | |        '-(integer)-'  |                                       |   
   | +-REAL------------------+                                       |   
   | |         .-PRECISION-. |                                       |   
   | '-DOUBLE--+-----------+-'                                       |   
   |           .-(34)-.                                              |   
   +-DECFLOAT--+------+----------------------------------------------+   
   |           '-(16)-'                                              |   
   |                    .-(1)-------.                                |   
   +---+-+-CHARACTER-+--+-----------+----------+--+--------------+---+   
   |   | '-CHAR------'  '-(integer)-'          |  '-FOR BIT DATA-'   |   
   |   '-+-+-CHARACTER-+--VARYING-+--(integer)-'                     |   
   |     | '-CHAR------'          |                                  |   
   |     '-VARCHAR----------------'                                  |   
   |            .-(1)-------.                                        |   
   +-+-GRAPHIC--+-----------+-+--------------------------------------+   
   | |          '-(integer)-' |                                      |   
   | '-VARGRAPHIC--(integer)--'                                      |   
   |           .-(1)-------.                                         |   
   +-+-BINARY--+-----------+---------+-------------------------------+   
   | |         '-(integer)-'         |                               |   
   | '-+-BINARY VARYING-+--(integer)-'                               |   
   |   '-VARBINARY------'                                            |   
   '-+-DATE------------------------------------------------+---------'   
     +-TIME------------------------------------------------+             
     |            .-(--6--)-------.  .-WITHOUT TIME ZONE-. |             
     '-TIMESTAMP--+---------------+--+-------------------+-'             
                  '-(--integer--)-'  '-WITH TIME ZONE----'               

source-values:

>>-(VALUES-+-| values-single-row |-------+-)-------------------->
           |                         (1) |     
           '-| values-multiple-row |-----'     

                               .-,-----------.     
   .-AS-.                      V             |     
>--+----+--correlation-name--(---column-name-+-)---------------><

Notes:
  1. The NOT ATOMIC clause must be specified when values-multiple-row is specified.

values-single-row:

>>-+-+-expression-+-------------+------------------------------><
   | '-NULL-------'             |   
   |   .-,------------------.   |   
   |   V                    |   |   
   '-(-----+-expression-+---+-)-'   
           '-NULL-------'           

values-multiple-row:

>>-+-+-expression----------+---------+-------------------------->
   | '-host-variable-array-'         |   
   |   .-,-----------------------.   |   
   |   V                         |   |   
   '-(---+-expression----------+-+-)-'   
         +-host-variable-array-+         
         '---NULL--------------'         

                                   (1)   
>--FOR--+-host-variable----+--ROWS-----------------------------><
        '-integer-constant-'             

Notes:
  1. For a static MERGE statement, if FOR n ROWS is not specified, values-multiple-row is treated as values-single-row. For a dynamic MERGE statement, FOR n ROWS does not need to be specified in the MERGE statement. It can be specified in the EXECUTE statement, but cannot be specified in both the MERGE and EXECUTE statements.

matching-condition:

>>-+-----+--MATCHED--------------------------------------------><
   '-NOT-'            

modification-operation:

>>-+-UPDATE SET--| assignment-clause |-+-----------------------><
   '-| insert-operation |--------------'   

assignment-clause:

   .-,------------------------------------------------------.       
   V                                                        | (1)   
>>---+-column-name--=--+-expression-+---------------------+-+-----><
     |                 +-DEFAULT----+                     |         
     |                 '-NULL-------'                     |         
     |    .-,-----------.           .-,--------------.    |         
     |    V             |           V                |    |         
     '-(----column-name-+--)--=--(----+-expression-+-+--)-'         
                                      +-DEFAULT----+                
                                      '-NULL-------'                

Notes:
  1. The number of expressions, DEFAULT, and NULL keywords must match the number of column-names.

insert-operation:

                                                               (1)             
>>-INSERT--+-----------------------+--VALUES--+-+-expression-+-------------+-><
           |    .-,-----------.    |          | +-DEFAULT----+             |   
           |    V             |    |          | '-NULL-------'             |   
           '-(----column-name-+--)-'          |   .-,--------------.       |   
                                              |   V                |   (2) |   
                                              '-(---+-expression-+-+-)-----'   
                                                    +-DEFAULT----+             
                                                    '-NULL-------'             

Notes:
  1. The number of expressions, DEFAULT, and NULL keywords must match the number of column-names.
  2. The number of columns in the SELECT list must match the number of column-names.

Description

INTO table-name or view-name
Identifies the target of the insert or update operations of the MERGE statement. The name must identify a table or view that exists at the current server. The name must not identify:
  • A catalog table
  • Start of changeA directory tableEnd of change
  • A created global temporary table
  • A read-only view
  • A system-maintained materialized query table
  • A table that is implicitly created for an XML column
  • Start of changeAn accelerator-only tableEnd of change

If a view is specified as the target of the MERGE statement, the view must not be defined with any INSTEAD OF triggers.

AS correlation-name
correlation-name provides an alternate name that can be used when referencing columns of the intermediate result table. If no correlation-name is specified, the name of the intermediate result table is the name of the target table or view of the MERGE statement. Otherwise, the name is the correlation-name.
include-columns
Specifies a set of columns that are included, along with the columns of the specified table or view, in the result table of the MERGE statement when it is nested in the FROM clause of the outer fullselect that is used in a SELECT statement, or in a SELECT INTO statement. The included columns are appended to the end of the list of columns that are identified by table-name or view-name. If a value is not specified for an included column, a null value is returned for that column.
INCLUDE
Introduces a list of columns that is to be included in the result table of the MERGE statement. The included columns are only available if the MERGE statement is nested in the FROM clause of a SELECT statement or a SELECT INTO statement. INCLUDE can only be specified when the MERGE statement is nested in the FROM clause of a SELECT statement.
column-name
Specifies the name for a column of the result table of the MERGE statement that is not the same name as another included column or a column in the table or view that is specified in table-name or view-name.
data-type
Specifies the data type of the included column. The included columns are nullable.
Columns with the following data types can not be used as INCLUDE columns:
  • LONG VARCHAR,
  • LONG VARGRAPHIC,
  • XML
  • LOBs
  • distinct types that are based on any of the listed data types.
built-in-type
Specifies a built-in data type. See CREATE TABLE for a description of each built-in type.
distinct-type
Specifies a distinct type. Any length, precision, or scale attributes for the column are those of the source type of the distinct type as specified by using the CREATE TYPE statement.
Start of changeUSING source-valuesEnd of change
Specifies the row or rows to be merged into the target table or view. VALUES values-single-row specifies a single row of source data. VALUES values-multiple-row specifies multiple rows of source data.
expression
Specifies an expression of the type that is described in Expressions. The expression must not include a column name. The expression must not reference a NEXT VALUE or PREVIOUS VALUE expression. If the expression is a single host variable, the host variable can identify a structure. Any host variable or structure that is specified must be described in the application program according to the rules for declaring host structures and variables.

Start of changeIf the expression is a host variable, or if a host variable is being explicitly cast, the host variable can include an indicator variable or an indicator array (in the case of a host structure). Either indicator variables or indicator arrays can be enabled for extended indicator variables.End of change

To provide a null value, specify the NULL keyword on a CAST specification.

Start of changeNULLEnd of change
Start of changeSpecifies a null value.

The column of the source-table corresponding to the NULL keyword is used to determine the data type of the null value. The column of the source-table must be referenced elsewhere in the MERGE statement such that its data type can be determined from the context in which it is used, and all such references must resolve to the same data type. References to date-time data types and CHAR or VARCHAR are considered the same type.

End of change
host-variable-array
Specifies a host variable array. Each host variable array must be defined in the application program in accordance with the rules for declaring an array. A host variable array contains the data to merge into a target column. The number of rows must be less than or equal to the dimension of each of the host variable arrays. An optional indicator array can be specified for each host variable array. An indicator array should be specified if the SQLTYPE of any SQLVAR occurrence indicates that a column is nullable. Start of changeThe indicator array can be enabled for extended indicator variables. End of changeThe dimension of the indicator array must be large enough to contain an indicator for each row of input data.

A host structure is not supported in host-variable-array.

host-variable-array is supported in C/C++, COBOL, and PL/I.

FOR host-variable or integer-constant ROWS
Specifies the number of rows to merge. For a dynamic MERGE statement, this clause can be specified on the EXECUTE statement. host-variable or integer-constant is assigned to a value k. If host-variable is specified, it must be an exact numeric type with a scale of zero and must not include an indicator variable. k must be in the range of 1 to 32767. k rows are merged into the target from the specified source data.

If a parameter marker is specified in FOR n ROWS, a value must be provided with the USING clause of the associated EXECUTE statement.

AS correlation-name
Specifies a correlation name for the source-values.
column-name
Specifies a column name to associate the input data to the SET assignment-clause for an update operation or the VALUES clause for an insert operation.
ON search-condition
Specifies join conditions between the source-values and the target table or view.

Each column-name in the search condition must name a column of the target table, view, or source-values. A subquery is not allowed in the search-condition. If a column-name exists in both the target and the source-values, the column name must be qualified.

For each row of the source-values, the search-condition is applied to each row of the target. If the search-condition is evaluated as true and the target is not empty, the specified WHEN MATCHED clause is used. Otherwise, the specified WHEN NOT MATCHED clause is used.

WHEN MATCHED or WHEN NOT MATCHED
Specifies the condition under which the modification-operation is run.
WHEN MATCHED
Specifies the operation to perform on the rows where the ON search-condition is true and the target is not empty. Only UPDATE can be specified after the THEN clause. WHEN MATCHED must not be specified more than one time.
WHEN NOT MATCHED
Specifies the operation to perform on the rows where the ON search-condition is false or unknown, or the target is empty. Only INSERT can be specified after the THEN clause. WHEN NOT MATCHED must not be specified more than one time.
THEN update-operation or THEN insert-operation
Specifies the operation to run when the matching-condition evaluates to true.
UPDATE SET
Specifies the update operation to run when the matching-condition evaluates to true.

Start of changeWhen extended indicator variables are enabled, a column of the source table must not be referenced multiple times in a single modification-operation. Extended indicator variables are enabled when EXTENDEDINDICATOR(YES) is used, or when the WITH EXTENDED INDICATORS prepare attribute has been specified for the MERGE statement.End of change

The rows that are updated from a source-row are subject to more updates by subsequent source-rows in the same statement. The update is cumulative.

Start of changeAn update-operation in a MERGE statement will not rest the AREO* status on a table.End of change

assignment-clause
Specifies a list of column updates.
column-name
Identifies a column to update. column-name must identify a column of the specified table or view, and that column must be updatable. The column must not be a generated column, or a column of a view that is derived from a scalar function, a constant, or an expression. column-name can also identify an included column. The same column-name must not be specified more than one time. A view column that is derived from the same column as another column of the view can be updated, but both columns cannot be updated in the same MERGE statement.

Assignments to included columns are only processed when the MERGE statement is nested in the FROM clause of a SELECT statement or a SELECT INTO statement. There must be at least one assignment clause that specifies a column-name that is not an included column.

expression
Specifies the new value of the column. The expression is any expression of the type that is described in Expressions. The expression must not include an aggregate function.

An expression can contain references to columns of source-values or target table or view. A column name is first checked as a column of the target, and then checked as a column of the source table. For each row that is updated, the value of a target column in an expression is the value of the column in the row before the row is updated. expression cannot contain references to an included column.

Start of changeIf expression is a reference to a single column of the source-values, the source-values column value might have been specified with an extended indicator variable value. The effects of such indicator variables apply to the corresponding target columns of the assignment-clause.End of change

Start of changeWhen extended indicator variables are enabled, an expression must not be more complex than a reference to a single column of the source table, or a single host variable if the indicator is set to an extended indicator value of default (-5) or unassigned (-7). In addition, a CAST specification can be used if either:
  • The target column is defined as nullable.
  • the target column is defined as NOT NULL with a non-null default, the source of the CAST specification is a single host variable, and the data attributes (data type, length, precision, and scale) of the host variable are the same as the result of the cast specification.
End of change
DEFAULT
Specifies the default value for the column. DEFAULT can be specified only for columns that have a default value. The value that is assigned depends on how the column is defined. For more information about default values, see the description of the DEFAULT clause in CREATE TABLE.
NULL
Specifies the null value as the new value of the column. Specify NULL only for nullable columns.
insert-operation
Specifies the insert operation that is to be executed for the rows where the matching-condition evaluates to true.

The rows that are inserted from a source-row are immediately subject for update by subsequent source-row in the same statement.

INSERT
Specifies a list of column names and row value expressions to use for the insert operation.
The number of values for the row in the row-value expression must be equal to the number of names in the insert column list. The first value is inserted into the first column in the list, the second value into the second column, and so on.
column-name
Specifies the columns for which the insert values are provided. Each name must identify a column of the table or view.

If an included column is not specified in the list of column names, the value of the included column is set to null. The column list cannot contain only included columns.

Start of changeThe same column must not be specified more than one time. A view column that cannot accept insert values must not be specified. A view column that cannot accept insert values must not be specified.End of change

If the object of the operation is a view that contains columns that cannot accept insert values, a list of column names must be specified and the list must not specify these columns.

Omission of the column list is an implicit specification of a list in which every column of the table (that is not defined as implicitly hidden) or view is identified in left-to-right order. This list is established when the statement is prepared and therefore does not include columns that were added to the table after the statement was prepared.

VALUES
Introduces one or more rows of values to insert.
expression
Start of changeSpecifies an expression of the type that does not include a column name of the target. If expression is a host variable, the host variable can include an indicator variable, or in the case of a host structure, an indicator array. When extended indicator variables are enabled, an expression must not be more complex than a reference to a single host variable if the indicator is set to an extended indicator value of default (-5) or unassigned (-7).
In addition, a CAST specification can be used if either:
  • The target column is defined as nullable.
  • the target column is defined as NOT NULL with a non-null default, the source of the CAST specification is a single host variable, and the data attributes (data type, length, precision, and scale) of the host variable are the same as the result of the cast specification.
End of change
DEFAULT
Specifies to assign the default value to the column. DEFAULT must only be specified for columns that have a default value. If the column is specified in the INCLUDE column list, the column value is set to null.

DEFAULT must be specified for a column that is defined as GENERATED ALWAYS. A valid value can be specified for a column that is defined as GENERATED BY DEFAULT.

NULL
Specifies the null value as the value of the column. Specify NULL only for nullable columns.
NOT ATOMIC CONTINUE ON SQLEXCEPTION

The rows of input data are processed separately. Any statement level triggers are processed for each row of source data that is processed, and the transition table includes the individual row that was processed. When errors are encountered and this option is in effect, processing continues, and some of the specified rows will not be processed. In this case, if an appropriate trigger is defined on the underlying base table, the statement level trigger will only be activated for rows that were successfully processed.

Regardless of the failure of any particular source row, the MERGE statement will not undo any changes that are made to the database by the statement. Merge will be attempted for rows that follow the failed row. However, the minimum level of atomicity is at least that of a single source row (that is, it is not possible for a partial merge to complete), including any triggers that might have been activated as a result of the MERGE statement.

QUERYNO integer
Specifies the number for this SQL statement that is used in EXPLAIN output and trace records. The number is used for the QUERYNO column of the plan table for the rows that contain information about this SQL statement. This number is also used in the QUERYNO column of the SYSIBM.SYSSTMT and SYSIBM.SYSPACKSTMT catalog tables.

If QUERYNO is not specified, the number that is associated with the SQL statement is the statement number that is assigned during precompilation. Thus, if the application program is changed and then precompiled, the statement number might change.

Notes

Trigger considerations:
A MERGE statement might cause triggers to be activated. A trigger might cause other statements to be executed or raise error conditions depending on the source data values. A before-update or before-insert trigger processes immediately before the update or insert operation.

If a source row results in an insert, any after-insert triggers are activated after the insert operation completes.

If a source row results in updates, any after-update triggers are activated after all of the update operations complete.

SQLCA and GET DIAGNOSTICS considerations:
The GET DIAGNOSTICS statement can be used immediately after the MERGE statement to check which input rows fail during the merge operation. The GET DIAGNOSTICS statement information item, NUMBER, indicates the number of conditions that are raised. The GET DIAGNOSTICS condition information item, DB2_ROW_NUMBER, indicates the input source rows that cause an error.
Indexes with VARBINARY columns:
Suppose that the identified table has an index on a VARBINARY column or a column that is a distinct type that is based on VARBINARY data type. In that case, that index column cannot specify the DESC attribute. To use the SQL data change operation on the identified table, either drop the index or alter the data type of the column to BINARY and then rebuild the index.
Considerations for a MERGE without a column list in insert-operation:
A MERGE statement without a specified column list as part of insert-operation does not include implicitly hidden columns. Therefore, such columns must have a defined default value.
Considerations for non-atomic processing of a MERGE statement:
When NOT ATOMIC is specified, the rows of source data are processed separately. Any references to special registers, sequence expressions, and functions in the MERGE statement are evaluated as each row of source data is processed. Statement level triggers are activated as each row of source data is processed.

If one or more errors occur during the operation for a row of source data, processing continues. The row that was being processed at the time of the error is not inserted or updated. Execution continues with the next row to be processed, and any other changes that are made during the execution of the multiple-row MERGE statement are not backed out. However, the processing of an individual row is an atomic action.

DRDA considerations:
DB2 Connect™ Version 9.1 and subsequent releases support the MERGE statement. The support is for CLI only, with no embedded static SQL support.

When you run a MERGE statement at a DB2® for z/OS® requester, cases might exist where the requestor does not know the number of rows in the source table. This situation includes the following cases:

  • For static or dynamic MERGE statements, of the FOR n ROWS clause contains a constant value for n.
  • For dynamic MERGE statements, of host variables are specified on the USING clause of an EXECUTE statement.

For both of these cases, if the number of rows in the source table is not known, the requester might send more data than is required to the server. The number of rows that are processed is correct because the server knows the correct numbers of rows to process. However, performance might be adversely affected. Consider the following example:

...long serial num [10];
struct { short len;
char data [18];
       }
name[20]...
EXEC SQL 
MERGE INTO T1
  USING (VALUES (:serial_num, :name))
  FOR 5 ROWS...

When this statement is run at the requester, the number of rows to merge (five) is not known. As a result, the requester sends 10 values for serial-name and name to the server because 10 is the size of the smallest host variable array and is, therefore, the maximum number of rows that can merge without causing an error.

Do the following to help minimize performance problems:

  • Avoid using numeric constants in the FOR n ROWS clause of the MERGE statement. For static MERGE statements, avoiding numeric constants ensures that the values for n are known at the requester.
  • For dynamic MERGE statements, use the USING DESCRIPTOR clause instead of the USING host-variable clause on the EXECUTE statement. If a USING DESCRIPTOR clause is used on the EXECUTE statement, the value for n must be indicated in the descriptor.
  • If either of the previous methods cannot be used, perform the following actions:
    • Make your host variable arrays as small as possible, or declare that the size of your host variable arrays are the size of n in the descriptor. This action avoids sending many unused host variable array entries to the server.
    • Ensure that varying length string arrays are initialized to a length of 0 (zero). Doing so minimizes the amount of data that is sent to the server.
    • Ensure that decimal host variable arrays are initialized to valid values. Doing so causes the requester to avoid sending a negative SQLCODE if the requester encounters invalid decimal data.
Start of changeExtended indicator variable usage:End of change
Start of changeWhen extended indicator variables are enabled, negative indicator values outside the range of -1 through -7 must not be specified. Also, the default and unassigned extended indicator values must not be used in contexts in which they are not supported.End of change
Start of changeExtended indicator variables in the assignment-clause:End of change
Start of changeAssigning the extended indicator a value of unassigned leaves the target column set to its current value, as if it had not been specified in the statement. Assigning the extended indicator a value of default assigns the default value to the column.

The assignment-clause must not assign all target columns to an extended indicator value of unassigned.

End of change
Start of changeExtended indicator variables in the insert-operation:End of change
Start of changeIn insert-operation, a value of unassigned sets the column to its default value.End of change
Start of changeExtended indicator variables and update triggers:End of change
Start of changeIf a target column is assigned an extended indicator value of unassigned, that column is not considered to have been updated. That column is treated as if it had not been specified in the OF column-name list of any update trigger that is defined on the target table.End of change
Start of changeExtended indicator variables and insert triggers:End of change
Start of changeThe activation of insert triggers is not affected by the use of extended indicator variables. Suppose that all columns in the implicit or explicit column list are assigned an extended indicator value of unassigned or default. Then, assume that an insert operation where all columns are assigned to the respective default values is attempted. If that operation is successful, the insert trigger is activated.End of change
Start of changeTable space data compression during an insert operation:End of change
Start of change If the table space is defined with the COMPRESS YES option, and data is inserted into a table in the table space, the first rows are stored uncompressed. When a amount of data that is determined by DB2 is inserted into the table, a compression dictionary is created and stored in the table space. The rows that are inserted into the table after the dictionary is created are stored compressed by using the compression dictionary.End of change
Start of changeSystem-period temporal tables:End of change
Start of change When a MERGE statement is processed for a system-period temporal table, the rows are affected in the same way as if the specific data change operation was invoked.End of change
Start of changeTables with enforced row and column access controls:End of change
Start of changeFor information about how enabled row permissions and column masks affect the update and insert operations in the MERGE statement, see the INSERT and UPDATE statement information.End of change

Examples

Example 1: Update the descriptions for activities that exist in the RECORDS table. Otherwise, insert the activity and its description into the RECORDS table.
MERGE INTO RECORDS AR
  USING (VALUES (:hv_activity, :hv_description)
    FOR :hv_nrows ROWS)
    AS AC (ACTIVITY, DESCRIPTION)
  ON (AR.ACTIVITY = AC.ACTIVITY)
  WHEN MATCHED THEN UPDATE SET DESCRIPTION = AC.DESCRIPTION
  WHEN NOT MATCHED THEN INSERT (ACTIVITY, DESCRIPTION)
     VALUES (AC.ACTIVITY, AC.DESCRIPTION)
  NOT ATOMIC CONTINUE ON SQLEXCEPTION;
Example 2: Use the transaction data to merge rows into the account table. Update the balance from the transaction data against an account ID and insert new accounts from the transaction data where the accounts do not already exist.
MERGE INTO ACCOUNT AS A
  USING (VALUES (:hv_id, :hv_amount) 
    FOR 3 ROWS)
    AS T (ID, AMOUNT)
  ON (A.ID = T.ID)
  WHEN MATCHED THEN UPDATE SET BALANCE = A.BALANCE + T.AMOUNT
  WHEN NOT MATCHED THEN INSERT (ID, BALANCE) 
      VALUES (T.ID, T.AMOUNT)
  NOT ATOMIC CONTINUE ON SQLEXCEPTION;
Example 3: Update the list of activities that are organized by group A in the RECORDS table. Update the activities information (description and date when last modified) in the RECORDS table if the activities exist in the RECORDS table and are also organized by group A. Insert new activities into the RECORDS table.
-- hv_nrows = 3
-- hv_activity(1) = 'D'; hv_description(1) = 'Dance'; hv_date(1) = '03/01/07'
-- hv_activity(2) = 'S'; hv_description(2) = 'Singing'; hv_date(2) = '03/17/07'
-- hv_activity(3) = 'T'; hv_description(3) = 'Tai-chi'; hv_date(3) = '05/01/07'
-- hv_group = 'A';
-- note that hv_group is not an array. All 3 values contain the same values
MERGE INTO RECORDS AR
  USING (VALUES (:hv_activity, :hv_description, :hv_date, :hv_group)
     FOR :hv_nrows ROWS)
     AS AC (ACTIVITY, DESCRIPTION, DATE, GROUP)
  ON AR.ACTIVITY = AC.ACTIVITY AND AR.GROUP = AC.GROUP
  WHEN MATCHED 
  THEN UPDATE SET (DESCRIPTION, DATE, LAST_MODIFIED)
                  = (AC.DESCRIPTION, AC.DATE, CURRENT TIMESTAMP)
  WHEN NOT MATCHED
  THEN INSERT (GROUP, ACTIVITY, DESCRIPTION, DATE, LAST_MODIFIED)
     VALUES (AC.GROUP, AC.ACTIVITY, AC.DESCRIPTION, AC.DATE, CURRENT TIMESTAMP)
  NOT ATOMIC CONTINUE ON SQLEXCEPTION;