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