首批通过分布式安全可靠测评,为关键业务系统打造
嵌套表
更新时间:2026-03-26 17:56:44
嵌套表是在 PL 程序中可以引用和模仿数组的非永久表。
功能适用性
该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版暂不支持。
用户可以定义一个表类型,然后声明这种类型的变量。之后,用户就可以将记录添加到用户的 PL 表中,并且采用与引用数组元素大体相同的方法引用记录。
语法如下:
TYPE type_name IS TABLE OF
{column_type | variable%TYPE | table.column%TYPE } [NOT NULL] | table%ROWTYPE
PL 嵌套表表类型支持的取值方法如下表所示。
| 方法 | 描述 |
|---|---|
| EXISTS(n) | 如果第 n 个行存在,则返回 True。 |
| COUNT | 返回这个 PL 表的行数。 |
| FIRST | LAST | 返回第一行和最后一行(最小和最大)的行号。如果 PL 表中没有数据,则返回空。 |
| PRIOR(n) | 返回 PL 表中第 n 行记录的前一条记录的行号。 |
| NEXT(n) | 返回 PL 表中第 n 行记录的后一条记录的行号。 |
| DELETE |
|
嵌套表示例如下,PL 表的记录被删除后,其他记录的行号不会因此移动。
obclient> CREATE TABLE departments(department_id number(4),department_name varchar2(15));
Query OK, 0 rows affected
obclient> INSERT INTO departments VALUES(10,'Administration');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(20,'Marketing');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(30,'Purchasing');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(40,'Human Resources');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(50,'Shipping');
Query OK, 1 row affected
obclient> INSERT INTO departments VALUES(60,'IT');
Query OK, 1 row affected
obclient> DECLARE
TYPE t_dept_table IS TABLE OF departments%ROWTYPE INDEX BY BINARY_INTEGER;
tab_department T_DEPT_TABLE;
v_count number(2) :=6;
BEGIN
-- 为表赋值
FOR int IN 1 .. v_count LOOP
SELECT * INTO tab_department(int) FROM departments WHERE department_id=int*10;
END LOOP;
-- 利用 COUNT 打印总行数
DBMS_OUTPUT.PUT_LINE(tab_department.COUNT||' ROW(S): ');
-- 利用 FIRST 和 LAST 打印所有行
FOR int IN TAB_department.FIRST .. TAB_department.LAST LOOP
DBMS_OUTPUT.PUT_LINE('Department number: '||tab_department(int).department_id);
DBMS_OUTPUT.PUT_LINE('Department name: '|| tab_department(int).department_name);
END LOOP;
-- 利用 EXISTS 检查记录
IF tab_department.EXISTS(5) THEN
DBMS_OUTPUT.PUT_LINE('ROW 5 EXISTS');
ELSE
DBMS_OUTPUT.PUT_LINE('ROW 5 NOT EXISTS');
END IF;
-- 用 DELETE 删除一个范围
DBMS_OUTPUT.PUT_LINE('Delete row 2-3');
tab_department.DELETE(2,3);
-- 用 NEXT 从前向后打印记录
DBMS_OUTPUT.PUT_LINE('Looping from first');
v_count := 1;
WHILE v_count IS NOT NULL
LOOP
DBMS_OUTPUT.PUT_LINE(tab_department(v_count).department_id);
v_count := tab_department.next(v_count);
END LOOP;
-- 用 PRIOR 从后向前打印,注意此时 COUNT 为 4
DBMS_OUTPUT.PUT_LINE('Looping from last');
v_count := tab_department.COUNT;
WHILE v_count IS NOT NULL
LOOP
DBMS_OUTPUT.PUT_LINE(tab_department(v_count).department_id);
v_count := tab_department.prior(v_count);
END LOOP;
END;
/
Query OK, 0 rows affected
6 ROW(S):
Department number: 10
Department name: Administration
Department number: 20
Department name: Marketing
Department number: 30
Department name: Purchasing
Department number: 40
Department name: Human Resources
Department number: 50
Department name: Shipping
Department number: 60
Department name: IT
ROW 5 EXISTS
Delete row 2-3
Looping from first
10
40
50
60
Looping from last
40
10
嵌套表与数组的主要区别
从概念上讲,嵌套表就像具有任意数量元素的一维数组。嵌套表与数组的主要区别如下:
数组可以声明元素数量,嵌套表则没有。嵌套表的大小可以动态增加。
数组总是密集的。嵌套表最初是密集的,但可以从中删除元素,因而可以变得稀疏。
嵌套表的适用场景
嵌套表适用于以下场景:
未设置元素数量。
索引值不是连续的。
需要要删除或更新某些元素,但不能同时删除或更新所有元素。