嵌套表是一種將正整數與值相關聯的集合。

嵌套表具有以下特征:

  • 必須定義嵌套表類型,之后可以為該嵌套表類型聲明嵌套表變量。使用嵌套表變量(或簡稱為“表”)進行數據操作。
  • 聲明嵌套表變量時,嵌套表最初不存在(它是一個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