Specifying direct row access by using row IDs

For some applications, you can use the value of a ROWID column to navigate directly to a row.

Before you begin

Ensure that the query qualifies for direct row access. To qualify, the search condition must be a Boolean term, stage 1 predicate that fits one of the following criteria:
  • A simple Boolean term predicate of the following form:
    RID (table designator) = noncolumn expression
    Where the noncolumn expression contains a result of a RID function.
  • A compound Boolean term that combines several simple predicates by using the AND operator, where one of the simple predicates fits the first criteria.

About this task

Introductory concepts

A ROWID column uniquely identifies each row in a table. With ROWID columns you can write queries that navigate directly to a row in the table because the column implicitly contains the location of the row. You can define a ROWID column as either GENERATED BY DEFAULT or GENERATED ALWAYS:

  • If you define the column as GENERATED BY DEFAULT, you can insert a value. Db2 provides a default value if you do not supply one. However, to be able to insert an explicit value (by using the INSERT statement with the VALUES clause), you must create a unique index on that column.
  • If you define the column as GENERATED ALWAYS (which is the default), Db2 always generates a unique value for the column. You cannot insert data into that column. In this case, Db2 does not require an index to guarantee unique values.

When you select a ROWID column, the value implicitly contains the location of the retrieved row. If you use the value from the ROWID column in the search condition of a subsequent query, Db2 can choose to navigate directly to that row.

If you define a column in a table to have the ROWID data type, Db2 provides a unique value for each row in the table only if you define the column as GENERATED ALWAYS. The purpose of the value in the ROWID column is to uniquely identify rows in the table.

You can use a ROWID column to write queries that navigate directly to a row, which can be useful in situations where high performance is a requirement. This direct navigation, without using an index or scanning the table space, is called direct row access. In addition, a ROWID column is a requirement for tables that contain LOB columns. This topic discusses the use of a ROWID column in direct row access.

For example, suppose that an EMPLOYEE table is defined in the following way:

CREATE TABLE EMPLOYEE
  (EMP_ROWID   ROWID NOT NULL GENERATED ALWAYS,
   EMPNO       SMALLINT,
   NAME        CHAR(30),
   SALARY      DECIMAL(7,2),
   WORKDEPT    SMALLINT);
The following code uses the SELECT from INSERT statement to retrieve the value of the ROWID column from a new row that is inserted into the EMPLOYEE table. This value is then used to reference that row for the update of the SALARY column.
EXEC SQL BEGIN DECLARE SECTION;
  SQL TYPE IS ROWID hv_emp_rowid;
  short             hv_dept, hv_empno;
  char              hv_name[30];
  decimal(7,2)      hv_salary;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL 
  SELECT EMP_ROWID INTO :hv_emp_rowid 
  FROM FINAL TABLE (INSERT INTO EMPLOYEE
                    VALUES (DEFAULT, :hv_empno, :hv_name, :hv_salary, :hv_dept));
EXEC SQL
  UPDATE EMPLOYEE
  SET SALARY = SALARY + 1200
  WHERE EMP_ROWID = :hv_emp_rowid;

EXEC SQL COMMIT;

For Db2 to be able to use direct row access for the update operation, the SELECT from INSERT statement and the UPDATE statement must execute within the same unit of work. Alternatively, you can use a SELECT from MERGE statement. The MERGE statement performs INSERT and UPDATE operations as one coordinated statement.

Requirement: To use direct row access, you must use a retrieved ROWID value before you commit. When your application commits, it releases its claim on the table space. After the commit, if a REORG is run on your table space, the physical location of the rows might change.
Restriction: In general, you cannot use a ROWID column as a key that is to be used as a single column value across multiple tables. The ROWID value for a particular row in a table might change over time due to a REORG of the table space. In particular, you cannot use a ROWID column as part of a parent key or foreign key.

The value that you retrieve from a ROWID column is a varying-length character value that is not monotonically ascending or descending (the value is not always increasing or not always decreasing). Therefore, a ROWID column does not provide suitable values for many types of entity keys, such as order numbers or employee numbers.

Procedure

To specify direct row access by using ROWID values:

Call the RID built-in function in the search condition of a SELECT, DELETE, or UPDATE statement.
The RID function returns the RID of a row, which you can use to uniquely identify a row.
Restriction: Because Db2 might reuse RID numbers when the REORG utility is run, the RID function might return different values when invoked for a row multiple times.

If you specify a RID and Db2 cannot locate the row through direct row access, Db2 does not switch to another access method. Instead, Db2 returns no rows.