DELETE

The DELETE statement deletes rows from a table or view or activates an instead of delete trigger. The table or view can be at the current server or any DB2® subsystem with which the current server can establish a connection. Deleting a row from a view deletes the row from the table on which the view is based if no instead of trigger is defined for the delete operation on this view. If such a trigger is defined, the trigger is activated instead of the delete operation.

There are two forms of this statement:

  • The searched DELETE form is used to delete one or more rows, optionally determined by a search condition.
  • The positioned DELETE form specifies that one or more rows corresponding to the current cursor position are to be deleted.

Invocation

This statement can be embedded in an application program or issued interactively. A positioned DELETE is embedded in an application program. Both the embedded and interactive forms are executable statements that can be dynamically prepared.

Authorization

Authority requirements depend on whether the object identified in the statement is a user-defined table, a catalog table, or a view, and whether the statement is a searched DELETE and SQL standard rules are in effect:

When a table other than a catalog table is identified: The privilege set must include at least one of the following:

  • The DELETE privilege on the table
  • Ownership of the table
  • DBADM authority on the database that contains the table
  • SYSADM authority

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

When a catalog table is identified: The privilege set must include at least one of the following:

  • DBADM authority on the catalog database
  • SYSCTRL authority
  • SYSADM authority

When a view is identified: The privilege set must include at least one of the following:

  • The DELETE privilege on the view
  • SYSADM authority
Start of changeIf the search-condition in a searched DELETE contains a reference to a column of the table or view, or the expression in the assignment-clause contains a reference to a column of the table or view, the privilege set must include at least one of the following:
  • The SELECT privilege on the table or view
  • Ownership of the table or view
  • DBADM authority on the database that contains the table, if the target is a table and that table that is not a catalog table
  • DATAACCESS
  • SYSADM authority
End of change

Start of changeIf the search-condition in a searched DELETE includes a subquery, or if the assignment-clause includes a scalar-fullselect or a row-fullselect, see Authorization for an explanation of the authorization required. End of change

The owner of a view, unlike the owner of a table, might not have DELETE authority on the view (or might have DELETE authority without being able to grant it to others). The nature of the view itself can preclude its use for DELETE. For more information, see the description of authority in CREATE VIEW.

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.)

searched delete:

Read syntax diagram
>>-DELETE FROM--+-table-name-+--+-------------------+----------->
                '-view-name--'  '-| period-clause |-'   

>--+------------------+--+--------------------+----------------->
   '-correlation-name-'  '-| include-column |-'   

>--+----------------------------+------------------------------->
   '-SET--| assignment-clause |-'   

>--+-------------------------+---------------------------------->
   '-WHERE--search-condition-'   

   .------------------------------.                         
   V  (1)                         |                         
>--------+----------------------+-+--+------------------+------><
         +-| isolation-clause |-+    '-QUERYNO--integer-'   
         '-SKIP LOCKED DATA-----'                           

Notes:
  1. The same clause must not be specified more than one time.

positioned delete:

Read syntax diagram
>>-DELETE FROM--+-table-name-+--+------------------+------------>
                '-view-name--'  '-correlation-name-'   

>--WHERE CURRENT OF--cursor-name-------------------------------->

>--+------------------------------------------+----------------><
   '-FOR ROW--+-host-variable----+--OF ROWSET-'   
              '-integer-constant-'                

Start of change

period-clause:

End of change
Read syntax diagram
>>-FOR PORTION OF BUSINESS_TIME--FROM--value1--TO--value2------><

include-column:

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----'               

assignment clause:

Read syntax diagram
   .-,-----------------------------------------------------------.   
   V                                                             |   
>>---+-column-name=-+-expression-+-----------------------------+-+-><
     |              '-NULL-------'                             |     
     |   .-,-----------.           .-,-------------------.     |     
     |   V             |           V  (1)                |     |     
     '-(---column-name-+-)--=--(-+--------+-expression-+-+-+-)-'     
                                 |        '-NULL-------'   |         
                                 |                (2)      |         
                                 '-row-fullselect----------'         

Notes:
  1. The number of expressions 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.

isolation-clause:

Read syntax diagram
>>-WITH--+-RR-+------------------------------------------------><
         +-RS-+   
         '-CS-'   

Description

FROM table-name or view-name
Identifies the table or view from which rows are to be deleted. The name must identify a table or view that exists at the DB2 subsystem that is identified by the implicitly or explicitly specified location name. The name must not identify:
  • An auxiliary table
  • A catalog table for which deletes are not allowed
  • A view of such a catalog table
  • Start of changeA directory tableEnd of change
  • A read-only view (see CREATE VIEW)
  • A system-maintained materialized query table
  • A table that is implicitly created for an XML column
In an IMS™ or CICS® application, the DB2 subsystem that contains the identified table or view must be a remote server that supports two-phase commit.
Start of changeperiod-clauseEnd of change
Start of changeSpecifies that a period clause applies to the target of the delete operation. The same period name must not be specified more than one time. The table reference must not specify a view.
FOR PORTION OF BUSINESS_TIME
Specifies that the delete only applies to row values for the portion of the BUSINESS_TIME period in the row that is specified by the period clause. BUSINESS_TIME must be a period that is defined on the table.

FOR PORTION OF BUSINESS_TIME must not be specified if the value of the CURRENT TEMPORAL BUSINESS_TIME special register is not NULL when the BUSTIMESENSITIVE bind option is set to YES.

FROM value1 TO value2
Specifies that the delete operation applies to rows for the period that is specified from value1 to value2. No rows are deleted if value1 is greater than or equal to value2, or if value1 or value2 is the null value.

For the period condition that is specified with FROM value1 TO value2, the period that is specified by period-name in a row of the target table of the delete:

  • Overlaps the beginning of the specified period if the value of the begin column is less than value1 and the value of the end column is greater than value1.
  • Overlaps the end of the specified period if the value of the end column is greater than or equal to value2 and the value of the begin column is less than value2.
  • Is fully contained within the specified period if the value for the begin column for period-name in the row is greater than or equal to value1 and the value for the corresponding end column in the row is less than or equal to value2.
  • Is partially contained in the specified period if the row overlaps the beginning of the specified period or the end of the specified period.
  • Fully overlaps the specified period if the period in the row overlaps the beginning of the specified period and overlaps the end of the specified period, .
  • Is not contained in the period if both columns of period-name are less than or equal to value1 or are greater than value2.

If the period period-name in a row is not contained in the specified period, the row is not deleted. Otherwise, the delete operation is applied based on the specification of the PORTION OF clause and how the values in the columns of period-name overlap the specified period as follows:

  • If the period period-name in a row is fully contained within the specified period, the row is deleted.
  • If the period period-name in a row is partially contained in the specified period and overlaps the beginning of the specified period:
    • The row is deleted.
    • Start of changeA row is inserted using the original values from the row, except that the end column is set to value1, and new values are used for other generated columns.End of change
  • If the period period-name in a row is partially contained in the specified period and overlaps the end of the specified period:
    • The row is deleted.
    • Start of changeA row is inserted using the original values from the row, except that the begin column is set to value2, and new values are used for other generated columns.End of change
  • If the period period-name in a row fully overlaps the specified period:
    • The row is deleted.
    • Start of changeA row is inserted using the original values from the row, except that the end column is set to value1, and new values are used for other generated columns.End of change
    • Start of changeAn additional row is inserted using the original values from the row, except that the begin column is set to value2, and new values are used for other generated columns.End of change

Any existing delete triggers are activated for the rows that are deleted, and any existing insert triggers are activated for the rows that are implicitly inserted.

value1, value2
Specifies expressions that return a value of a built-in data type. The result of each expression must be comparable to the data type of the columns of the specified period. See the comparison rules described in Assignment and comparison. Each expression can contain any of the following supported operands:
  • A constant
  • A special register
  • A variable
  • A built-in scalar function whose arguments are supported operands
  • A CAST specification where the cast operand is a supported operand
  • An expression that uses arithmetic operators and operands

Start of changeEach expression must not have a timestamp precision that is greater than the precision of the columns for the period.End of change

Start of changeIf the begin and end columns of the period are defined as TIMESTAMP WITHOUT TIME ZONE, each expression must not return a value of a timestamp with a time zone.End of change

End of change
correlation-name
Specifies an alternate name that can be used within the search-condition to designate the table or view. (For an explanation of correlation names, see Correlation names.)
include-column
Specifies a set of columns that are included, along with the columns of table-name or view-name, in the result table of the DELETE statement when it is nested in the FROM clause of the outer fullselect that is used in a subselect, SELECT statement, or in a SELECT INTO statement. The included columns are appended to the end of the list of columns that is identified by table-name or view-name. If no value is assigned to a column that is specified by an include-column, a NULL value is returned for that column.
INCLUDE
Introduces a list of columns that are to be included in the result table of the DELETE statement. The included columns are only available if the DELETE statement is nested in the FROM clause of a SELECT statement or a SELECT INTO statement.
column-name
Specifies the name for a column of the result table of the DELETE statement that is not the same name as another included column nor 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.
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.
SET
Introduces the assignment of values to columns.
assignment-clause
The assignment-clause introduces a list of one or more column-names and the values that are to be assigned to the columns. The column-names are the only columns that can be set using the assignment-clause.
column-name
Identifies an INCLUDE column.

Assignments to included columns are only processed when the DELETE statement is nested in the FROM clause of a SELECT statement or a SELECT INTO statement. The columns that are named in the INCLUDE clause are the only columns that can be set using the SET clause. The null value is returned for an included column that is not set by using an explicit SET clause.

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

A column-name in an expression must identify a column of the table or view. For each row that is deleted, the value of the column in the expression is the value of the column in the row before the row is deleted.

NULL
Specifies the null value as the new value of the column. Specify NULL only for nullable columns.
row-fullselect
Specifies a fullselect that returns a single row. The column values are assigned to each of the corresponding column-names. If the fullselect returns no rows, the null value is assigned to each column; an error occurs if any column that is to be deleted is not nullable. An error also occurs if there is more than one row in the result.

If the fullselect refers to columns that are to be deleted, the value of such a column in the fullselect is the value of the column in the row before the row is deleted.

WHERE
Specifies the rows to be deleted. You can omit the clause, give a search condition, or specify a cursor. For a created temporary table or a view of a created temporary table, you must omit the clause. When the clause is omitted, all the rows of the table or view are deleted.
search-condition
Is any search condition as described in Language elements. Each column-name in the search condition, other than in a subquery, must identify a column of the table or view.

The search condition is applied to each row of the table or view and the deleted rows are those for which the result of the search condition is true.

If the search condition contains a subquery, the subquery can be thought of as being executed each time the search condition is applied to a row, and the results used in applying the search condition. In actuality, a subquery with no correlated references is executed just once, whereas it is possible that a subquery with a correlated reference must be executed once for each row.

Let T2 denote the object table of a DELETE statement and let T1 denote a table that is referred to in the FROM clause of a subquery of that statement. T1 must not be a table that can be affected by the DELETE on T2. Thus, the following rules apply:

  • T1 must not be a dependent of T2 in a relationship with a delete rule of CASCADE or SET NULL, unless the result of the subquery is materialized before the DELETE action is executed.
  • T1 must not be a dependent of T3 in a relationship with a delete rule of CASCADE or SET NULL if deletes of T2 cascade to T3.
WHERE CURRENT OF cursor-name
Identifies the cursor to be used in the delete operation. cursor-name must identify a declared cursor as explained in the description of the DECLARE CURSOR statement in DECLARE CURSOR. If the DELETE statement is embedded in a program, the DECLARE CURSOR statement must include select-statement rather than statement-name.

The table or view named must also be named in the FROM clause of the SELECT statement of the cursor, and the result table of the cursor must be capable of being deleted. For an explanation of read-only result tables, see Read-only cursors. Note that the object of the DELETE statement must not be identified as the object of the subquery in the WHERE clause of the SELECT statement of the cursor.

If the cursor is ambiguous and the plan or package was bound with CURRENTDATA(NO), DB2 might return an error to the application if DELETE WHERE CURRENT OF is attempted for any of the following:

  • A cursor that is using block fetching
  • A cursor that is using query parallelism
  • A cursor that is positioned on a row that has been modified by this or another application process

When the DELETE statement is executed, the cursor must be open and positioned on a row or rowset of the result table.

  • If the cursor is positioned on a single row, that row is the one deleted, and after the deletion the cursor is positioned before the next row of its result table. If there is no next row, the cursor positioned after the last row.
  • If the cursor is positioned on a rowset, all rows corresponding to the rows of the current rowset are deleted, and after the deletion the cursor is positioned before the next rowset of its result table. If there is no next rowset, the cursor positioned after the last rowset.

A positioned DELETE must not be specified for a cursor that references a view on which an instead of delete trigger is defined, even if the view is an updatable view.

FOR ROW n OF ROWSET
Specifies which row of the current rowset is to be deleted. The corresponding row of the rowset is deleted, and the cursor remains positioned on the current rowset. If the rowset consists of a single row, or all other rows in the rowset have already been deleted, then the cursor is positioned before the next rowset of the result table. If there is no next rowset, the cursor is positioned after the last rowset.

host-variable or integer-constant is assigned to an integral value k. If host-variable is specified, it must be an exact numeric type with scale zero, must not include an indicator variable, and k must be in the range of 1 to 32767. The cursor must be positioned on a rowset, and the specified value must be a valid value for the set of rows most recently retrieved for the cursor.

If the specified row cannot be deleted, an error is returned. It is possible that the specified row is within the bounds of the rowset most recently requested, but the current rowset contains less than the number of rows that were implicitly or explicitly requested when that rowset was established.

If, via a positioned delete against a sensitive static cursor that specifies a particular row of the current rowset, and that row has been identified as a delete hole (that is, a row in the result table whose corresponding row has deleted from the base table), an error is returned.

If, via a positioned delete against a sensitive static cursor that specifies a particular row of the current rowset, and that row has been identified as an update hole (that is, a row in the result table whose corresponding row has been updated so that it no longer satisfies a predicate of the SELECT statement), an error is returned.

It is possible for another application process to delete a row in the base table of the SELECT statement so that the specified row of the cursor no longer has a corresponding row in the base table. An attempt to delete such a row results in an error.

If the FOR ROW n OF ROWSET clause is not specified, the current position of cursor determines the rows that are affected by the statement:

  • If the cursor is positioned on a single row, that row is the one deleted. After the row is deleted, the cursor is positioned before the next row of its result table. If there is no next row, the cursor positioned after the last row.
  • If the cursor is positioned on a rowset, all rows corresponding to the rows of the current rowset are deleted. After the rows are deleted, the cursor is positioned before the next rowset of its result table. If there is no next rowset, the cursor positioned after the last rowset.
isolation-clause
Specifies the isolation level used when locating the rows to be deleted by the statement.
WITH
Introduces the isolation level, which may be one of the following:
RR
Repeatable read
RS
Read stability
CS
Cursor stability

The default isolation level of the statement is the isolation level of the package or plan in which the statement is bound, with the package isolation taking precedence over the plan isolation. When a package isolation is not specified, the plan isolation is the default.

SKIP LOCKED DATA
The SKIP LOCKED DATA clause specifies that rows are skipped when incompatible locks are held on the row by other transactions. These rows can belong to any accessed table that is specified in the statement. SKIP LOCKED DATA can be used only when isolation CS or RS is in effect and applies only to row level or page level locks.

For DELETE statements, SKIP LOCKED DATA can be specified only in the searched form of the DELETE statement. SKIP LOCKED DATA is ignored if it is specified when the isolation level that is in effect is repeatable read (WITH RR) or uncommitted read (WITH UR). The default isolation level of the statement depends on the isolation level of the package or plan with which the statement is bound, with the package isolation taking precedence over the plan isolation. When a package isolation is not specified, the plan isolation is the default.

QUERYNO integer
Specifies the number to be used for this SQL statement 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 the clause is omitted, the number associated with the SQL statement is the statement number assigned during precompilation. Thus, if the application program is changed and then precompiled, that statement number might change.

Using the QUERYNO clause to assign unique numbers to the SQL statements in a program is helpful:

  • For simplifying the use of optimization hints for access path selection
  • For correlating SQL statement text with EXPLAIN output in the plan table

For information on using optimization hints, such as enabling the system for optimization hints and setting valid hint values, and for information on accessing the plan table, see Managing DB2 Performance.

Notes

Delete operation errors:
If an error occurs during the execution of any delete operation, no changes are made. If an error occurs during the execution of a positioned delete, the position of the cursor is unchanged. However, it is possible for an error to make the position of the cursor invalid, in which case the cursor is closed. It is also possible for a delete operation to cause a rollback, in which case the cursor is closed.
Position of cursor:
If an application process deletes a row on which any of its cursors are positioned, those cursors are positioned before the next row of the result table. Let C be a cursor that is positioned before row R (as a result of an OPEN, a DELETE through C, a DELETE through some other cursor, or a searched DELETE). In the presence of an SQL data change statements that affect the base table from which R is derived, the next FETCH operation referencing C does not necessarily position C on R. For example, the operation can position C on R', where R' is a new row that is now the next row of the result table.
Locking:
Unless appropriate locks already exist, one or more exclusive locks are acquired during the execution of a successful delete operation. Until the locks are released by a commit or rollback operation, the effect of the delete operation can only be perceived by the application process that performed the deletion and the locks can prevent other application processes from performing operations on the table. Locks are not acquired when rows are deleted from a declared temporary table unless all the rows are deleted (DELETE FROM T). When all the rows are deleted from a declared temporary table, a segmented table lock is acquired on the pages for the table and no other table in the table space is affected.
Triggers:
Delete operations can cause triggers to be activated. A trigger might cause other statements to be executed or might raise error conditions that are based on the deleted rows. If a DELETE statement on a view causes an INSTEAD OF trigger to be activated, referential integrity is checked against the updates that are performed in the trigger and not against the underlying tables of the view that cause the trigger to be activated.
Start of changeTriggers defined on a table for which row or column access control is also enforced:End of change
Start of changeRow permissions and column masks are not applied to the initial values of transition variables and transition tables. Row and column access control that is enforced for the triggering table is also ignored for any transition variables or transition tables that are referenced in the trigger body or that are passed as arguments to user-defined functions that are invoked in the trigger body. To ensure that no security concern exists for SQL statements in the trigger action (access to sensitive data in transition variables and transition tables, for example), the trigger must be secure. For information about securing a trigger, see CREATE TRIGGER and ALTER TRIGGER.End of change
Referential integrity:
If the identified table or the base table of the identified view is a parent, the rows selected must not have any dependents in a relationship with a delete rule of RESTRICT or NO ACTION. In addition, the delete operation must not cascade to descendent rows that have dependents in a relationship with a delete rule of RESTRICT or NO ACTION.

If the delete operation is not prevented by a RESTRICT or NO ACTION delete rule, the selected rows are deleted and any rows that are dependents of the selected rows are also deleted.

  • The nullable columns of foreign keys in any rows that are their dependents in a relationship governed by a delete rule of SET NULL are set to the null value.
  • Any rows that are their dependents in a relationship governed by a delete rule of CASCADE are also deleted, and these rules apply, in turn, to those rows.

The only difference between NO ACTION and RESTRICT is when the referential constraint is enforced. RESTRICT (IBM® SQL rules) enforces the rule immediately, and NO ACTION (SQL standard rules) enforces the rule at the end of the statement. This difference matters only in the case of a searched DELETE involving a self-referencing constraint that deletes more than one row. NO ACTION might allow the DELETE to be successful where RESTRICT (if it were allowed) would prevent it.

Check constraint:
A check constraint can prevent the deletion of a row in a parent table when there are dependents in a relationship with a delete rule of SET NULL. If deleting a row in the parent table would cause a column in a dependent table to be set to null and there is a check constraint that specifies that the column must not be null, the row is not deleted.
Start of changeReferential constraints defined on a table for which row or column access control is enforced:End of change
Start of changeRow and column access controls do not effect referential constraints.End of change
Nesting user-defined functions or stored procedures:
A DELETE statement can implicitly or explicitly refer to user-defined functions or stored procedures. This is known as nesting of SQL statements. A user-defined function or stored procedure that is nested within the DELETE must not access the table from which you are deleting rows.
Indexes with VARBINARY columns:
If 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, 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.
Number of rows deleted:
Except as noted below, a delete operation sets SQLERRD(3) in the SQLCA to the number of deleted rows. This number does not include any rows that were deleted as a result of a CASCADE delete rule or a trigger.

DELETE FROM T without a WHERE clause deletes all rows of T. If a table T is contained in a segmented table space and is not a parent table, this deletion will be performed without accessing T. The SQLERRD(3) field is set to -1. (For a complete description of the SQLCA, including exceptions to the above, see SQL communication area (SQLCA).

Rules for positioned DELETE with SENSITIVE STATIC scrollable cursor:
When a SENSITIVE STATIC scrollable cursor has been declared, the following rules apply:
  • Delete attempt of delete holes or update holes. If, with a positioned delete against a SENSITIVE STATIC scrollable cursor, an attempt is made to delete a row that has been identified as a delete hole (that is, a row in the result table whose corresponding row has been deleted from the base table), an error occurs.

    If an attempt is made to delete a row that has been identified as an update hole (that is, a row in the result table whose corresponding row has been updated so that it no longer satisfies the predicate of the SELECT statement), an error occurs.

  • Delete operations. Positioned delete operations with SENSITIVE STATIC scrollable cursors perform as follows:
    1. The SELECT list items in the target row of the base table of the cursor are compared with the values in the corresponding row of the result table (that is, the result table must still agree with the base table). If the values are not identical, the delete operation is rejected and an error occurs. The operation can be attempted again after a successful FETCH SENSITIVE has occurred for the target row.
    2. The WHERE clause of the SELECT statement is re-evaluated to determine whether the current values in the base table still satisfy the search criteria. The values in the SELECT list are compared to determine that these values have not changed. If the WHERE clause evaluates as true, and the values in the SELECT list have not changed, the delete operation is allowed to proceed. Otherwise, an error occurs, the delete operation is rejected, and an update hole appears in the cursor.
    3. After the base table row is successfully deleted, the temporary result table is updated and the row is marked as a delete hole.
  • Rollback of delete holes. Delete holes are usually permanent. Once a delete hole is identified, it remains a delete hole until the cursor is closed. However, if a positioned delete using this cursor actually caused the creation of the hole (that is, this cursor was used to make the changes that resulted in the hole) and the delete was subsequently rolled back, then the row is no longer considered a delete hole.
  • Result table. Any deletes, either positioned or searched, to rows of the base table on which a SENSITIVE STATIC scrollable cursor is defined are reflected in the result table if a positioned update or positioned delete is attempted with the scrollable cursor. A SENSITIVE STATIC scrollable cursor sees these deletes when a FETCH SENSITIVE is attempted.

If the FOR ROW n OF ROWSET clause is not specified, the entire rowset fetched by the most recent FETCH statement that returned data for the specified cursor is deleted.

Deleting rows from a table with multilevel security:
When you delete rows from a table with multilevel security, DB2 compares the security label of the user (the primary authorization ID) to the security label of the row. The delete proceeds according to the following rules:
  • If the security label of the user and the security label of the row are equivalent, the row is deleted.
  • If the security label of the user dominates the security label of the row, the user's write-down privilege determines the security the result of the DELETE statement:
    • If the user has write-down privilege or write-down control is not enabled, the row is deleted.
    • If the user does not have write-down privilege and write-down control is enabled, the row is not deleted.
  • If the security label of the row dominates the security label of the user, the row is not deleted.
Start of changeDeleting rows from a table for which row and column access control is enforced:End of change
Start of changeWhen a DELETE statement is issued for a table for which row access control is enforced, the rules specified in the row permissions affect whether a row can be deleted. Typically those rules are based on the authorization ID or role of the process.

A table for which row access control is enforced has at least one row permission, the default row permission that prevents all access to the table. When multiple row permissions are defined and enabled for a table, a row access control search condition is derived by using the logical OR operator to the search condition in each enabled permission. This row access control search condition is applied to the table to determine which rows are accessible to the authorization ID or role of the DELETE statement. If the WHERE clause is specified in the DELETE statement, the user-specified predicates are applied on the accessible rows to determine the rows to be deleted. If there is no WHERE clause, the accessible rows are the rows to be deleted.

If there are rows to be deleted, and there is a DELETE trigger for the table, the trigger is activated.

When a DELETE statement is issued for a table for which column access control is enforced, column masks do not affect the DELETE statement.

The preceding rules are not applicable to include-columns. include-columns are subject to the rules for the select list because they are not the columns of the object table of the DELETE statement.

End of change
Other SQL statements in the same unit of work:
The following statements cannot follow a DELETE statement in the same unit of work:
  • An ALTER TABLE statement that changes the data type of a column (ALTER COLUMN SET DATA TYPE)
  • An ALTER INDEX statement that changes the padding attribute of an index with varying-length columns (PADDED to NOT PADDED or vice versa)
  • Start of changeA CREATE TABLE statement that creates an accelerator-only table.End of change
  • Start of changeAn INSERT, UPDATE or DELETE statement that updates an accelerator-only table from a different acceleratorEnd of change
Start of changeConsiderations for a system-period temporal table:End of change
Start of changeIf the DELETE statement has a search condition that contains a correlated subquery that references the history table (explicitly referencing the name of the history table or implicitly referenced through the use of a period specification in the FROM clause), the deleted rows that are stored as historical rows are potentially visible for delete operations for the rows that are subsequently processed for the statement.

The mass delete operation is not used for a DELETE statement that does not contain a search condition if the table is defined as a system-period temporal table.

End of change
Start of changeConsiderations for a history table:End of change
Start of changeWhen a row of a system-period temporal table is deleted, a historical copy of the row is inserted into the corresponding history table and the end timestamp of the historical row is captured in the form of a system determined value that corresponds to the time of the data change operation. DB2 generates a value using the time-of-day clock during execution of the first data change statement in the transaction that requires a value to be assigned to a row-begin or transaction-start-ID column in a table. This also occurs when a row in a system-period temporal table is deleted. DB2 ensures the uniqueness of the generated values for an end column in a history table across transactions. If a conflicting transaction is updating the same row in the system-period temporal table and the row that is to be inserted into the associated history table will have a value for the end column that is greater than the value of the corresponding begin column, an error is returned.End of change
Start of changeConsiderations for an application-period temporal table: End of change
Start of changeA DELETE statement that contains a FOR PORTION OF BUSINESS_TIME clause for an application-period temporal table indicates the two points in time between which the specified delete operations are effective.

Suppose that FOR PORTION OF BUSINESS_TIME is specified and the period value for a row is only partially contained in the period that is specified from value1 up to value2. (The period value for a row is specified by the values of the begin column and end column.) In this case, the row is deleted and one or two rows are automatically inserted to represent the portion of the row that is not deleted. For each row that is automatically inserted as a result of a delete operation on the table, new values are generated for each generated column in the application-period temporal table. If a generated column is defined as part of a unique or primary key, parent key in a referential constraint, or unique index, an automatic insert might violate a constraint or index. In this case, an error is returned.

End of change
Start of changeSyntax alternatives:End of change
Start of changeFor compatibility with other SQL implementations, the FROM keyword that immediately follows the DELETE keyword can be omitted.End of change

Examples

Assume that the statements in the examples are embedded in PL/I programs.

Example 1: From the table DSN8A10.EMP delete the row on which the cursor C1 is currently positioned.
  EXEC SQL DELETE FROM DSN8A10.EMP WHERE CURRENT OF C1;
Example 2: From the table DSN8A10.EMP, delete all rows for departments E11 and D21.
  EXEC SQL DELETE FROM DSN8A10.EMP
    WHERE WORKDEPT = 'E11' OR WORKDEPT = 'D21';
Example 3: From employee table X, delete the employee who has the most absences.
  EXEC SQL DELETE FROM EMP X
    WHERE ABSENT = (SELECT MAX(ABSENT) FROM EMP Y
    WHERE X.WORKDEPT = Y.WORKDEPT);
Example 4: Assuming that cursor CS1 is positioned on a rowset consisting of 10 rows of table T1, delete all 10 rows in the rowset.
EXEC SQL DELETE FROM T1 WHERE CURRENT OF CS1; 
Example 5: Assuming cursor CS1 is positioned on a rowset consisting of 10 rows of table T1, delete the fourth row of the rowset.
EXEC SQL DELETE FROM T1 WHERE CURRENT OF CS1 FOR ROW 4 OF ROWSET;