PL 嵌套表, 或者称为嵌套表,是可以在 PL 程序中可以引用、模仿数组的非永久表。用户可以定义一个表类型,然后声明这种类型的变量。之后,用户就可以将记录添加到用户的 PL 表中,并且采用与引用数组元素大体相同的方法引用记录。

    嵌套表包括两个基本成分:

    • 数据处理类型为 BINARY_INTEGER 主键

    • 标量或记录数据类型的列

    语法如下:

    1. TYPE type_name IS TABLE OF
    2. {column_type | variable%TYPE | table.column%TYPE } [NOT NULL] | table%ROWTYPE
    3. [ INDEX BY BINARY_INTEGER];

    PL 嵌套表表类型支持的取值方法如下:

    方法

    描述

    EXISTS(n)

    如果第 n 个行存在,则返回 true。

    COUNT

    返回这个 PL 表的行数。

    FIRST | LAST

    返回第一行和最后一行(最小和最大)的行号。如果 PL 表中没有数据,则返回空。

    PRIOR(n)

    返回 PL 表中第 n 行记录的前一条记录的行号。

    NEXT(n)

    返回 PL 表中第 n 行记录的后一条记录的行号。

    DELETE

    • DELETE 删除表中所有记录。

    • DELETE(n) 删除表中第n条记录。

    • DELETE(m,n) 删除行号 m 到 n 之间的所有记录。

    注意

    PL 表的记录被删除后,其他记录的行号不会因此移动。如下例所示:

    1. obclient> DECLARE
    2. -> TYPE T_dept_table IS TABLE OF
    3. -> departments%ROWTYPE INDEX BY BINARY_INTEGER;
    4. -> TAB_department T_dept_table;
    5. -> v_count number(2) :=6;
    6. -> BEGIN
    7. -> -- 为表赋值
    8. -> FOR int IN 1 .. v_count LOOP
    9. -> SELECT * INTO TAB_department(int) FROM departments WHERE department_id=int*10;
    10. -> END LOOP;
    11. ->
    12. -> -- 利用COUNT打印总行数
    13. -> DBMS_OUTPUT.PUT_LINE(TAB_department.COUNT||' ROW(S): ');
    14. -> -- 利用FIRSTLAST打印所有行
    15. -> FOR int IN TAB_department.FIRST .. TAB_department.LAST LOOP
    16. -> DBMS_OUTPUT.PUT_LINE('Department number: '||TAB_department(int).department_id);
    17. -> DBMS_OUTPUT.PUT_LINE('Department name: '|| TAB_department(int).department_name);
    18. -> END LOOP;
    19. ->
    20. -> -- 利用EXISTS检查记录
    21. -> IF TAB_department.EXISTS(5) THEN
    22. -> DBMS_OUTPUT.PUT_LINE('ROW 5 EXISTS');
    23. -> ELSE
    24. -> DBMS_OUTPUT.PUT_LINE('ROW 5 NOT EXISTS');
    25. -> END IF;
    26. ->
    27. -> -- DELETE删除一个范围
    28. -> DBMS_OUTPUT.PUT_LINE('Delete row 2-3');
    29. -> TAB_department.DELETE(2,3);
    30. ->
    31. -> -- NEXT从前向后打印记录
    32. -> DBMS_OUTPUT.PUT_LINE('Looping from first');
    33. -> v_count := 1;
    34. -> WHILE v_count IS NOT NULL
    35. -> LOOP
    36. -> DBMS_OUTPUT.PUT_LINE(TAB_department(v_count).department_id);
    37. -> v_count := TAB_department.next(v_count);
    38. -> END LOOP;
    39. ->
    40. -> -- PRIOR从后向前打印,注意此时COUNT4
    41. -> DBMS_OUTPUT.PUT_LINE('Looping from last');
    42. -> v_count := TAB_department.COUNT;
    43. -> WHILE v_count IS NOT NULL
    44. -> LOOP
    45. -> DBMS_OUTPUT.PUT_LINE(TAB_department(v_count).department_id);
    46. -> v_count := TAB_department.prior(v_count);
    47. -> END LOOP;
    48. -> END;
    49. -> /
    50. Query OK, 0 rows affected (0.18 sec)
    51. 6 ROW(S):
    52. Department number: 10
    53. Department name: Administration
    54. Department number: 20
    55. Department name: Marketing
    56. Department number: 30
    57. Department name: Purchasing
    58. Department number: 40
    59. Department name: Human Resources
    60. Department number: 50
    61. Department name: Shipping
    62. Department number: 60
    63. Department name: IT
    64. ROW 5 EXISTS
    65. Delete row 2-3
    66. Looping from first
    67. 10
    68. 40
    69. 50
    70. 60
    71. Looping from last
    72. 40
    73. 10