varray 或大小可变数组是一种将正整数与值相关联的集合。它在许多方面与嵌套表类似。

varray 具有以下特征:

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

TYPE IS VARRAY 语句用于在 SPL 程序的声明部分中定义 varray 类型。

TYPE varraytype IS { VARRAY | VARYING ARRAY }(maxsize)
  OF { datatype | objtype };

varraytype 是分配给 varray 类型的标识符。datatype 是标量数据类型,例如 VARCHAR2 或 NUMBER。maxsize 是该类型的 varray 中允许的最大元素数。objtype 是先前定义的对象类型。

CREATE TYPE 命令可用于定义可供数据库中所有 SPL 程序使用的 varray 类型。为了使用该 varray,必须使用声明一个该 varray 类型的变量。以下是声明 varray 变量的语法。

varray varraytype

varray 是分配给 varray 的标识符。varraytype 是先前定义的 varray 类型的标识符。

varray 使用 varray 类型的构造函数初始化。

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

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

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

以下是 varray 的构造函数示例:

DECLARE
    TYPE varray_typ IS VARRAY(2) OF CHAR(1);
    v_varray        varray_typ := varray_typ('A','B');

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

varray(n)[.element ]

varray 是先前声明的 varray 的标识符。n 是正整数。如果 varray 的 varray 类型是从对象类型定义的,那么 [.element ] 必须引用定义 varray 类型时所依据的对象类型中的属性。或者,可以通过省略 [.element ]来引用整个对象。

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

DECLARE
    TYPE dname_varray_typ IS VARRAY(4) OF VARCHAR2(14);
    dname_varray    dname_varray_typ;
    CURSOR dept_cur IS SELECT dname FROM dept ORDER BY dname;
    i               INTEGER := 0;
BEGIN
    dname_varray := dname_varray_typ(NULL, NULL, NULL, NULL);
    FOR r_dept IN dept_cur LOOP
        i := i + 1;
        dname_varray(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_varray(j));
    END LOOP;
END;

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

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