嵌套表 是一种将正整数与值相关联的集合。嵌套表具有以下特征:

  • 必须定义嵌套表类型,之后可以为该嵌套表类型声明嵌套表变量。使用嵌套表变量(或简称为“表”)进行数据操作。
  • 声明嵌套表变量时,嵌套表最初不存在(它是一个 null 集合)。必须使用构造函数 初始化 null 表。您还可以使用赋值语句初始化表,其中赋值的右侧是相同类型的初始化表。注:嵌套表的初始化在 Oracle 中是必需的,但在 SPL 中是可选的。
  • 键是正整数。
  • 构造函数确定表中的元素数。EXTEND 方法向表中添加了其他元素。注:使用构造函数来确定表中的元素数量以及使用 EXTEND 方法向表中添加其他元素在 Oracle 中是必需的,但在 SPL 中是可选的。
  • 表可能是稀疏的 - 在键值的赋值中可能存在间隙。
  • 尝试引用超出其初始化大小或扩展大小的表元素将导致 SUBSCRIPT_BEYOND_COUNT 异常。

TYPE IS TABLE 语句用于在 SPL 程序的声明部分中定义嵌套表类型。

TYPE tbltype IS TABLE OF { datatype | rectype | objtype };

tbltype 是分配给嵌套表类型的标识符。datatype 是标量数据类型,例如 VARCHAR2 或 NUMBER。rectype 是先前定义的记录类型。objtype 是先前定义的对象类型。

说明 您可以使用 CREATE TYPE 命令定义可供数据库中所有 SPL 程序使用的嵌套表类型。

为了使用该表,必须声明该嵌套表类型的变量。以下是声明表变量的语法。

  • table tbltype

    table 是分配给嵌套表的标识符。tbltype 是以前定义的嵌套表类型的标识符。

    使用嵌套表类型的构造函数初始化嵌套表。

  • tbltype ([ { expr1 | NULL } [, { expr2 | NULL } ] [, ...] ])

    tbltype 是嵌套表类型的构造函数的标识符,它与嵌套表类型具有相同的名称。expr1, expr2, … 是与表的元素类型兼容的表达式。如果指定 NULL,则会将相应的元素设置为 null。如果参数列表为空,则返回空的嵌套表,这意味着表中没有元素。如果表是从对象类型定义的,则 exprn 必须返回该对象类型的对象。对象可以是函数的返回值或对象类型的构造函数,或者对象可以是同一类型的另一个嵌套表的元素。

如果将 EXISTS 之外的集合方法应用于未初始化的嵌套表,则会引发 COLLECTION_IS_NULL 异常。

以下是嵌套表的构造函数示例:

DECLARE
    TYPE nested_typ IS TABLE OF CHAR(1);
    v_nested        nested_typ := nested_typ('A','B');

使用以下语法引用表的元素。

table(n)[.element ]

table 是先前声明的表的标识符。n 是正整数。如果从记录类型或对象类型定义表的表类型,则 [.element  ] 必须引用定义嵌套表类型时所依据的对象类型中的记录类型或属性内的单个字段。或者,可以通过省略 [.element  ] 来引用整个记录或对象。

以下是嵌套表的示例,已知其中将有四个元素。

DECLARE
    TYPE dname_tbl_typ IS TABLE OF VARCHAR2(14);
    dname_tbl       dname_tbl_typ;
    CURSOR dept_cur IS SELECT dname FROM dept ORDER BY dname;
    i               INTEGER := 0;
BEGIN
    dname_tbl := dname_tbl_typ(NULL, NULL, NULL, NULL);
    FOR r_dept IN dept_cur LOOP
        i := i + 1;
        dname_tbl(i) := r_dept.dname;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('DNAME');
    DBMS_OUTPUT.PUT_LINE('----------');
    FOR j IN 1..i LOOP
        DBMS_OUTPUT.PUT_LINE(dname_tbl(j));
    END LOOP;
END;

上面的示例生成以下输出:

DNAME
----------
ACCOUNTING
OPERATIONS
RESEARCH
SALES

以下示例从 emp 表中读取前十名员工的姓名,将它们存储在一个嵌套表中,然后显示表中的结果。编写的 SPL 代码假设事先不知道要返回的员工数量。

DECLARE
    TYPE emp_rec_typ IS RECORD (
        empno       NUMBER(4),
        ename       VARCHAR2(10)
    );
    TYPE emp_tbl_typ IS TABLE OF emp_rec_typ;
    emp_tbl         emp_tbl_typ;
    CURSOR emp_cur IS SELECT empno, ename FROM emp WHERE ROWNUM <= 10;
    i               INTEGER := 0;
BEGIN
    emp_tbl := emp_tbl_typ();
    DBMS_OUTPUT.PUT_LINE('EMPNO    ENAME');
    DBMS_OUTPUT.PUT_LINE('-----    -------');
    FOR r_emp IN emp_cur LOOP
        i := i + 1;
        emp_tbl.EXTEND;
        emp_tbl(i) := r_emp;
    END LOOP;
    FOR j IN 1..10 LOOP
        DBMS_OUTPUT.PUT_LINE(emp_tbl(j).empno || '     ' ||
            emp_tbl(j).ename);
    END LOOP;
END;

请注意创建一个空表,其中构造函数 emp_tbl_typ() 作为匿名块的可执行部分中的第一个语句。然后使用 EXTEND 集合方法针对从结果集返回的每个员工向表中添加元素。

以下是输出。

EMPNO    ENAME
-----    -------
7369     SMITH
7499     ALLEN
7521     WARD
7566     JONES
7654     MARTIN
7698     BLAKE
7782     CLARK
7788     SCOTT
7839     KING
7844     TURNER

以下示例显示如何使用对象类型  的嵌套表。首先,使用部门名称和位置的属性创建对象类型。

CREATE TYPE dept_obj_typ AS OBJECT (
    dname           VARCHAR2(14),
    loc             VARCHAR2(13)
);

以下匿名块定义一个嵌套表类型,其元素由 dept_obj_typ 对象类型组成。声明、初始化嵌套表变量,然后从 dept 表填充该变量。最后,显示嵌套表中的元素。

DECLARE
    TYPE dept_tbl_typ IS TABLE OF dept_obj_typ;
    dept_tbl        dept_tbl_typ;
    CURSOR dept_cur IS SELECT dname, loc FROM dept ORDER BY dname;
    i               INTEGER := 0;
BEGIN
    dept_tbl := dept_tbl_typ(
        dept_obj_typ(NULL,NULL),
        dept_obj_typ(NULL,NULL),
        dept_obj_typ(NULL,NULL),
        dept_obj_typ(NULL,NULL)
    );
    FOR r_dept IN dept_cur LOOP
        i := i + 1;
        dept_tbl(i).dname := r_dept.dname;
        dept_tbl(i).loc   := r_dept.loc;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('DNAME          LOC');
    DBMS_OUTPUT.PUT_LINE('----------     ----------');
    FOR j IN 1..i LOOP
        DBMS_OUTPUT.PUT_LINE(RPAD(dept_tbl(j).dname,14) || ' ' ||
            dept_tbl(j).loc);
    END LOOP;
END;
说明 包含嵌套表的构造函数 dept_tbl_typ 的参数是对对象类型的构造函数 dept_obj_typ 的调用。

以下是匿名块的输出。

DNAME          LOC
----------     ----------
ACCOUNTING     NEW YORK
OPERATIONS     BOSTON
RESEARCH       DALLAS
SALES          CHICAGO