使用行ID指定直接行访问

对于某些应用程序,您可以使用 ROWID 列的值直接导航到某一行。

准备工作

确保查询符合直接行访问的条件。 要符合条件,搜索条件必须是一个布尔值,第一阶段谓词符合以下标准之一:
  • 一个简单的布尔术语谓词,形式如下:
    RID (table designator) = noncolumn expression
    非列表达式包含RID函数的结果。
  • 一个布尔复合术语,使用“与”运算符将多个简单谓词组合在一起,其中一个简单谓词符合第一个条件。

关于本任务

入门概念

ROWID列用于唯一标识表格中的每一行。 使用ROWID列,您可以编写查询语句,直接跳转到表格中的某一行,因为该列隐含地包含了该行的位置。 您可以将 ROWID 列定义为默认生成或始终生成:

  • 如果将列定义为默认生成,则可以插入一个值。 Db2 如果您没有提供默认值,则系统会提供默认值。 但是,为了能够插入一个明确的值(通过使用带有VALUES子句的INSERT语句),您必须在该列上创建一个唯一的索引。
  • 如果将列定义为“始终生成”(默认设置),则 Db2 始终为该列生成一个唯一的值。 您不能在该列中插入数据。 在这种情况下, Db2 不需要索引来保证唯一值。

当您选择ROWID列时,该值隐含了所检索行的位置。 如果您在后续查询的搜索条件中使用 ROWID 列中的值, Db2 可以选择直接导航到该行。

如果您将表中的列定义为 ROWID 数据类型,则只有在将列定义为 GENERATED ALWAYS 时, Db2 才会为表中的每一行提供一个唯一的值。 ROWID列中值的目的是唯一标识表中的行。

您可以使用ROWID列编写直接跳转到某行的查询,这在需要高性能的情况下非常有用。 这种无需使用索引或扫描表空间的直接导航称为直接行访问。 此外,包含LOB列的表必须包含ROWID列。 本主题讨论了在直接行访问中使用ROWID列。

例如,假设雇员表定义如下:

CREATE TABLE EMPLOYEE
  (EMP_ROWID   ROWID NOT NULL GENERATED ALWAYS,
   EMPNO       SMALLINT,
   NAME        CHAR(30),
   SALARY      DECIMAL(7,2),
   WORKDEPT    SMALLINT);
以下代码使用INSERT语句中的SELECT来从插入到EMPLOYEE表的新行中获取ROWID列的值。 然后使用该值来更新工资列。
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;

为了使 Db2 能够使用直接行访问进行更新操作,SELECT from INSERT语句和UPDATE语句必须在同一工作单元内执行。 或者,您可以使用MERGE语句中的SELECT。 MERGE语句将INSERT和UPDATE操作作为一条协调语句执行。

要求 :要使用直接行访问,必须在提交前使用检索到的 ROWID 值。 当您的应用程序提交时,它就会释放对表空间的要求。 提交后,如果您的表空间运行了REORG,则行的物理位置可能会发生变化。
限制 :通常情况下,您不能将 ROWID 列用作跨多个表的单个列值。 由于表空间的REORG,表中特定行的ROWID值可能会随时间变化。 特别是,不能将 ROWID 列用作父键或外键的一部分。

从ROWID列中检索到的值是一个长度可变的字符值,它不是单调递增或递减的(该值并不总是增加或减少)。 因此,ROWID列无法为订单号或员工编号等多种实体键提供合适的值。

过程

使用 ROWID 值指定直接行访问:

在SELECT、DELETE或UPDATE语句的搜索条件中调用RID内置函数。
RID 函数用于返回行的 RID,您可以使用它来唯一标识行。
限制 :由于在运行REORG实用程序时, Db2 可能会重复使用RID编号,因此当对同一行多次调用RID函数时,可能会返回不同的值。

如果您指定了 RID,而 Db2 无法通过直接行访问找到该行,则 Db2 不会切换到其他访问方法。 相反, Db2 没有返回任何行。