联 系 我 们
售前咨询
售后咨询
微信关注:星环科技服务号
更多联系方式 >
6.8.12.10 Collections
更新时间:7/30/2024, 6:53:21 AM

Inceptor 中 PL/SQL 中的集合元素一共有三种形式,分别为 Associative arrays 数组,Nested tables 嵌套表,和 VARRAYs 变量数组。

  • VARRAR:可以看作是一个预先已经定义好长度的一维数组,可使用数字编号可以依次操作每个数组元素。

  • Nested tables:可以看作是一个一维数组,可使用数字编号可以依次操作每个数组元素,要在给变量赋值前,给变量分配空间。

  • Associative arrays:可以看作是一个数据字典,有 key、value 两列。key 值(键值)可以是任意数字和字符串,value 值可以是任意对象包括 collection 类型的对象。

其中,Associative arrays 可以定义键 key 的数据类型,而 Nested tables 和 VARRAR 默认都是整数键。

另外,Associative arrays 变量在赋值前不需要进行初始化,Nested tables 和 VARRAR 需要在赋值前进行初始化,否则会报 collection_is_null 异常。

VARRAY
  • VARRAY 是 collections 类型的一维,有界,且不稀疏的集合。

    • 有界(即在声明该类型的时候,需要定义一个最大范围)。

    • 不稀疏(在删除掉数组中的某一个元素时,会重新排序)。

  • VARRAY 类型的变量,可以不用赋初值。

  • 一般 VARRAY 类型和 VARRAY 变量的声明,仅在当前 PL/SQL 语句块中有效,但如果在包内声明 VARRAY 类型和 VARRAY 变量,就可以跨语句块的使用。

VARRAY 语法
VARRAY 类型的创建
DECLARE TYPE <varray_type> IS VARRAY(<variable-sized arrays>) OF <data_type>;
复制
  • <varray_type>:VARRAY 类型名称。

  • <variable-sized arrays>:VARRAY 中最大容纳的元素个数。声明一个 VARRAY 类型时,必须定义可变数组的最大范围。

  • <data_type>:VARRAY 中数据的数据类型。

例 102. 声明一个名为 varray_type 的 VARRAY 类型,最多可以容纳两个数据,数据的类型为 STRING.
DECLARE TYPE varray_type AS VARRAY(2) OF STRING;
复制
VARRAY 变量的创建
<v_varray_name>   <varray_type>
复制
  • <v_varray_name>:VARRAY 变量名称。

  • <varray_type>:VARRAY 类型。

例 103. 定义一个名为 v_varray_type 的 varray_type 类型的变量,语句如下:
v_varray_type   varray_type
复制
VARRAY 变量的赋值
<v_varray_name>(<variable-sized arrays>) := <value>
复制
  • <v_varray_name>:VARRAY 变量名称。

  • <variable-sized arrays>:VARRAY 中最大容纳的元素个数。

  • <value>:变量的值。

例 104. 给变量 v_varray_type(1) 赋值
v_varray_type(1):='name'
复制
VARRAY 声明与赋值
例 105. 变量的声明与赋值
!set plsqlUseSlash true
DECLARE
   -- 声明一个能保存 10 个 STRING 数据类型的成员的 VARRAY 数据类型 ORG_VARRAY_TYPE。
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   -- 定义一个 ORG_VARRAY_TYPE 类型的 VARRAY 变量 V_ORG_VARRAY。
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   -- 初始化变量 V_ORG_VARRAY 的值。
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   -- 输出变量 V_ORG_VARRAY 前 4 个成员的值。
   DBMS_OUTPUT.PUT_LINE('输出1:' || V_ORG_VARRAY(1) || ''|| V_ORG_VARRAY(2) || ''|| V_ORG_VARRAY(3) || ''|| V_ORG_VARRAY(4))
   -- 输出变量 V_ORG_VARRAY 第 5 个成员的值。
   DBMS_OUTPUT.PUT_LINE('输出2:' || V_ORG_VARRAY(5))
   -- 给变量 V_ORG_VARRAY 第 5 个成员赋值为 5001。
   V_ORG_VARRAY(5) := '5001'
   -- 再次输出变量 V_ORG_VARRAY 第 5 个成员的值。
   DBMS_OUTPUT.PUT_LINE('输出3:' || V_ORG_VARRAY(5))
END;
/
复制

输出结果为:

+------------------+
|    output        |
+------------------+
| 11234  |
| 25          |
| 35001       |
+------------------+
复制
VARRAY 类型的使用范围
例 106. 声明的 VARRAY 类型和 VARRAY 变量,仅在当前的 PL/SQL 语句块中生效
!set plsqlUseSlash true
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   FOR I IN V_ORG_VARRAY.FIRST()..V_ORG_VARRAY.LAST()
   LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
   END LOOP;
END;
/
复制

输出结果为:

COMPILE FAILED: Semantic error: [Error 11152]
ANONYMOUS BLOCK (LINE 2, COLUMN 3, TEXT "V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')"): Undefined identifier used in left or right side ASSIGN: V_ORG_VARRAY
复制

可以看到,上一个例子中声明的 VARRAY 类型和 VARRAY 变量,仅在当前的 PL/SQL 语句块中生效,在本例创建的 PL/SQL 语句块中,直接调用 VARRAY 类型和 VARRAY 变量,Inceptor 会报错。

NESTED TABLE
  • NESTED TABLE 是 collections 类型的一维,无边界,不稀疏的集合。

    • 无边界(在声明该类型的时候,不需要定义元素的最大个数,需要在给变量赋值之前,给变量分配空间)。

    • 不稀疏(在删除数组中的某个数据时,数组会重新排序)。

  • NESTED TABLE 类型即 PL/SQL 表类型,与 records 类型相似,是对记录类型的扩展。

  • 它可以处理多行记录,类似于C语言中的二维数组,使得可以在 PL/SQL 中模仿数据库中的表。

NESTED TABLE 语法
  • TYPE 可以为全部的数据类型,包括标量类型和复合类型。

  • 定义集合变量的时候,必须同时初始化集合元素,否则,Inceptor 会报错。

表类型的创建
DECLARE TYPE <table_type> IS TABLE OF <data_type>
复制
  • <table_type>:表类型名称。

  • <data_type>:数据类型。

例 107. 声明一个名为 list_of_names_t 的表类型,数据类型为 STRING
DECLARE TYPE list_of_names_t IS TABLE OF string
复制
表类型变量的创建
<v_table_name>  <table_type>
复制
  • <v_table_name>:表类型变量名称。

  • <table_type>:表类型。

例 108. 定义一个名为 children 的 list_of_names_t 类型的变量
children  list_of_names_t
复制
表类型变量的初始化
<v_table_name> := <value>
复制
  • <v_table_name>:表类型变量名称。

  • <value>:表变量的值。

例 109. 给变量 children 赋值
children := list_of_names_t ()
复制
NESTED TABLE 变量的声明与赋值
例 110. NESTED TABLE 变量的声明与赋值
!set plsqlUseSlash true
DECLARE
   -- 定义一个名为 list_of_names_t 的 table 类型,数据类型为字符串。
   TYPE list_of_names_t IS TABLE OF string
   -- 定义一个名为 happyfamily 的 list_of_names_t 变量,并对集合元素进行初始化。
   happyfamily list_of_names_t:=list_of_names_t ()
BEGIN
   -- 给变量 happyfamily 赋值前,为其分配一个大小为4的空间,也就是最多可以容纳 4 个元素。
   happyfamily.EXTEND (4)
   -- 依次给变量 happyfamily 赋值为 vera,chris,eli,steven。
   happyfamily (1) := 'Veva'
   happyfamily (2) := 'Chris'
   happyfamily (3) := 'Eli'
   happyfamily (4) := 'Steven'
   FOR idx IN 1 .. 4
   LOOP
   DBMS_OUTPUT.PUT_LINE(happyfamily(idx))
   END LOOP
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| Veva    |
| Chris   |
| Eli     |
| Steven  |
+---------+
复制
Associative arrays
  • Associative arrays 是 collections 类型的一维,无边界的稀疏集合,只能用于PL/SQL。

    • 无边界(在声明 Associative arrays 类型时,无需定义元素的最大个数,给变量赋值前也不需要使用 extend 方法给变量分配空间)。

    • 稀疏的(对于变量 Associative arrays 中的下标可以随意取值,并对该下标所对应的元素赋值)。

Associative arrays 语法
Associative arrays 类型的创建
DECLARE TYPE <table_type> IS TABLE OF <data_type> INDEX BY <index_type>
复制
  • <table_type>:Associative arrays 类型名称。

  • <data_type>:存储的值的数据类型。

  • <index_type>:key 的数据类型。

例 111. 声明一个名为 numbers_aat 的 Associative arrays 类型,存储的值为 INT 型,key 为 STRING 类型
DECLARE TYPE numbers_aat IS TABLE OF INT INDEX BY STRING
复制
Associative arrays 变量的创建
v_table_type  table_type
复制
  • <v_table_name>:表类型变量名称。

  • <table_type>:表类型。

例 112. 定义一个名为 l_numbers 的 numbers_aat 类型的变量
l_numbers numbers_aat
复制
Associative arrays 变量的赋值
<v_table_name>(<index>) := <value>
复制
  • <v_table_name>:变量名称。

  • <value>:变量的值。

  • <index>:

例 113. 给变量 l_numbers 中下标 key 为 '100' 的元素赋值
l_numbers ('100') := 12345
复制
Associative arrays 变量的声明和赋值
例 114. Associative arrays 变量的声明与赋值
!set plsqlUseSlash true
DECLARE
   -- 声明一个名为 numbers_aat 的 Associative arrays 类型,存储的值为字符串类型,key 为整数类型。
   TYPE numbers_aat IS TABLE OF STRING INDEX BY INT
   -- 定义一个整数类型的变量。
   l_row INT
   -- 定义一个名为 l_numbers 的 numbers_aat 变量。
   l_numbers numbers_aat
BEGIN
   -- 给变量 l_numbers 中下标为 100 的元素赋值为 LILY。
   l_numbers (100) := 'LILY'
   -- 给变量 l_numbers 中下标为 80 的元素赋值为 ALICE。
   l_numbers (80) := 'ALICE'
   -- 把变量 l_numbers 中第一个元素的下标赋值给 l_row。
   l_row:= l_numbers.first()
   -- 把变量 l_numbers 中第一个元素的下一个元素的下标赋值给 l_row。
   l_row:= l_numbers.next(l_row)
   -- 输出变量 l_numbers 中第一个元素的下一个元素的下标,及其所对应的值。
   DBMS_OUTPUT.put_line (l_row||' ' ||l_numbers(l_row))
END;
/
复制

输出结果为:

+-----------+
|  output   |
+-----------+
| 100 LILY  |
+-----------+
复制
Collections 方法
  • 集合变量的方法,在存储过程和函数中用于操作 collection 对象,但是都不能在 SQL 语句中直接使用。

  • 集合方法中调用的参数对应于 collection 的下标描述符,通常这些描述符都是数字,但是在 associative arrays 中,有可能是字符窜。

  • 如果对未初始化的 NESTED TABLE 或者 VARRAY 使用集合元素方法将返回 COLLECTION_IS_NULL 异常。

  • 对于类型 Associative arrays,将不支持任何集合元素方法。

COUNT()
  • 用于计算 VARRAYNESTED TABLE 中条目的个数。

  • 使用 DELETE 或者 TRIM 将减少 COUNT;使用 EXTEND 将增加 COUNT。

VARRAY
例 115. 利用 COUNT() 方法遍历 VARRAY 变量中的值
!set plsqlUseSlash true
DECLARE
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   -- 利用 COUNT() 方法计算出变量 V_ORG_VARRAY 条目的个数。
   FOR I IN 1..V_ORG_VARRAY.COUNT()
   LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| V(1)=1  |
| V(2)=2  |
| V(3)=3  |
| V(4)=4  |
| V(5)=5  |
+---------+
复制
NESTED TABLE
例 116. 使用 COUNT() 方法遍历 NESTED TABLE 变量中的值
!set plsqlUseSlash true
DECLARE
   -- 定义一个名为 list_of_names_t 的 table 类型,数据类型为字符串。
   TYPE list_of_names_t IS TABLE OF string
   -- 定义一个名为 happyfamily 的 list_of_names_t 变量,并对集合元素进行初始化。
   happyfamily list_of_names_t:=list_of_names_t ()
BEGIN
   -- 给变量 happyfamily 赋值前,为其分配一个大小为 4 的空间,也就是最多可以容纳 4 个元素。
   happyfamily.EXTEND (4)
   -- 依次给变量 happyfamily 赋值为 vera,chris,eli,steven。
   happyfamily (1) := 'Veva'
   happyfamily (2) := 'Chris'
   happyfamily (3) := 'Eli'
   happyfamily (4) := 'Steven'
   -- 使用 count 方法,依次打印出变量 happyfamily 的值。
   FOR l_row IN 1 .. happyfamily.COUNT()
   LOOP
      DBMS_OUTPUT.put_line (happyfamily (l_row))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| Veva    |
| Chris   |
| Eli     |
| Steven  |
+---------+
复制
Associative Arrays
例 117. 不能用 COUNT() 方法遍历 Associative arrays 变量中的值
!set plsqlUseSlash true
DECLARE
   TYPE numbers_aat IS TABLE OF STRING INDEX BY INT
   l_row INT
   l_numbers numbers_aat
BEGIN
   l_numbers (100) := 'LILY'
   l_numbers (90) := 'GRACE'
   l_numbers (80) := 'ALICE'
   l_numbers (95) := 'LISI'
   FOR l_row in 1..l_numbers.count()
   LOOP
      DBMS_OUTPUT.put_line (l_numbers(l_row))
   END LOOP;
END;
/
复制

输出结果为:

 EXECUTION FAILED: Task EXEC PLSQL error PLException: [Error 100] NO_DATA_FOUND
*********************************************
ANONYMOUS BLOCK (LINE 12, COLUMN 28, TEXT "l_numbers(l_row)")
*********************************************
复制
FIRST() 和 LAST()
  • 对于 VARRAY 和 NESTED TABLE 类型:

    • FIRST() 返回数组的第一个条目的下标。

    • LAST() 返回数组的最后一个条目的下标。

  • 对于 Associative arrays 类型:

    • FIRST() 返回数组中的最小下标。

    • LAST() 返回数组的最大下标。

VARRAY
例 118. 使用 FIRST() 和 LAST() 方法
!set plsqlUseSlash true
DECLARE
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   -- 使用 FIRST() 和 LAST() 方法分别返回变量 V_ORG_VARRAY 第一个条目的下标和最后一个条目的下标。
   FOR I IN V_ORG_VARRAY.FIRST()..V_ORG_VARRAY.LAST()
   LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| V(1)=1  |
| V(2)=2  |
| V(3)=3  |
| V(4)=4  |
| V(5)=5  |
+---------+
复制
Associative Arrays

由于 Associative arrays 类型的变量内的数据是稀疏的,所以使用 first() 和 last() 方法时,会分别返回变量中元素的所对应下标的最小值和最大值。

例 119. 使用 first() 和 last() 方法
!set plsqlUseSlash true
DECLARE
   -- 声明一个名为 numbers_aat 的 Associative arrays 类型,存储的值为字符串类型,key 为整数类型。
   TYPE numbers_aat IS TABLE OF STRING INDEX BY INT
   -- 定义一个名为 l_numbers 的 numbers_aat 变量。
   l_numbers numbers_aat
   -- 分别定义三个整数类型的变量。
   l_row INT
   first_numbers INT
   last_numbers INT
BEGIN
   -- 给变量 l_numbers 中的一些元素赋值,可以跳跃,也可以不按顺序。
   l_numbers(100) := 'LILY'
   l_numbers(90) := 'GRACE'
   l_numbers(80) := 'ALICE'
   l_numbers(95) := 'LISI'
   -- 使用 first() 和 last() 方法,分别将 l_numbers 中的第一个和最后一个元素的下标赋值给相应的变量。
   first_numbers :=l_numbers.first()
   last_numbers:=l_numbers.last()
   -- 依次打印出变量 l_numbers 中的第一个和最后一个元素。
   DBMS_OUTPUT.put_line ('the first one:'||l_numbers(first_numbers))
   DBMS_OUTPUT.put_line ('the last one:'||l_numbers(last_numbers))
END;
/
复制

输出结果为:

+----------------------+
|        output        |
+----------------------+
| the first one:ALICE  |
| the last one:LILY    |
+----------------------+
复制
PRIOR(n) 和 NEXT(n)
  • PRIOR(n):返回给定条目的前一个条目的下标,即 PRIOR(n) 和 n-1 是一样的。

  • NEXT(n):返回给定条目的后一个条目的下标,即 NEXT(n) 和 n+1 是一样的。

例 120. 使用 PRIOR(n) 方法
!set plsqlUseSlash true
DECLARE
   I INT
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   -- 利用 COUNT() 方法计算出变量 V_ORG_VARRAY 条目的个数,也就是变量 V_ORG_VARRAY 最后一个条目的下标,并赋值给 I。
   I := V_ORG_VARRAY.COUNT()
   WHILE I IS NOT NULL LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
      -- 返回 I 条目的前一个条目的下标,并赋值给 I。
      I := V_ORG_VARRAY.PRIOR(I)
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| V(5)=5  |
| V(4)=4  |
| V(3)=3  |
| V(2)=2  |
| V(1)=1  |
+---------+
复制
例 121. 使用 NEXT(n) 方法
!set plsqlUseSlash true
DECLARE
   I INT
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   -- 使用 FIRST() 返回变量 V_ORG_VARRAY 第一个条目的下标,并赋值给 I。
   I := V_ORG_VARRAY.FIRST()
   WHILE I IS NOT NULL LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
      -- 返回 I 条目的后一个条目的下标,并赋值给 I。
      I := V_ORG_VARRAY.NEXT(I)
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| V(1)=1  |
| V(2)=2  |
| V(3)=3  |
| V(4)=4  |
| V(5)=5  |
+---------+
复制
例 122. 同时使用 PRIOR(n) 方法和 NEXT(n) 方法
!set plsqlUseSlash true
DECLARE
   -- 声明一个整数类型的变量,并赋初值为 3。
   I INT default 3
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   -- 将变量 V_ORG_VARRAY 第三个元素的前一个元素的下标赋值给变量 I。
   I := V_ORG_VARRAY.PRIOR(I)
   -- 在 LOOP 循环内,将变量 V_ORG_VARRAY 第三个元素的后一个元素的下标赋值给变量 I,也就是说在 LOOP 循环内将打印出第三个元素之后的所有元素。
   WHILE I IS NOT NULL LOOP
       DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
       I := V_ORG_VARRAY.NEXT(I)
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| V(2)=2  |
| V(3)=3  |
| V(4)=4  |
| V(5)=5  |
+---------+
复制
EXTEND(k)
  • 用于为 nested table 或者 VARRAY 分配空间,在不大于元素的最大个数的情况下,为已经赋值的集合变量增加条目个数;不加参数的情况下,默认只添加一个条目。

  • 不能用于Associative arrays类型的变量。

  • 新增的条目没有值(默认为 NULL),但是你可以对它们进行初始化。

  • COUNT() 和 LAST() 方法可以反映 VARRAY 新的容量。

  • 对 VARRA 的扩展不可以超过其最大容量。

  • 对 VARRAY 扩展前必须要对其进行初始化。

VARRAY
例 123. 使用 EXTEND(k) 方法
!set plsqlUseSlash true
DECLARE
   -- 声明一个 INT 类型的变量 I。
   I INT
   -- 声明一个能保存 10 个 STRING 数据类型的成员的 VARRAY 数据类型 ORG_VARRAY_TYPE。
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   -- 定义一个 ORG_VARRAY_TYPE 类型的 VARRAY 变量 V_ORG_VARRAY。
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   -- 初始化变量 V_ORG_VARRAY 的值。
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   -- 将变量 V_ORG_VARRAY 最后一个条目的下标赋值给 I。
   I:=V_ORG_VARRAY.LAST()
   -- 给变量 V_ORG_VARRAY 的最后追加两个新的条目。
   V_ORG_VARRAY.EXTEND(2)
   -- 给变量 V_ORG_VARRAY 新追加的第一个条目赋值为 6。
   V_ORG_VARRAY(I + 1) := '6'
   -- 给变量 V_ORG_VARRAY 新追加的第一个条目赋值为 7。
   V_ORG_VARRAY(I + 2) := '7'
   FOR idx IN 1 .. V_ORG_VARRAY.COUNT()
   LOOP
   DBMS_OUTPUT.PUT_LINE(V_ORG_VARRAY(idx))
   END LOOP
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| 1       |
| 2       |
| 3       |
| 4       |
| 5       |
| 6       |
| 7       |
+---------+
复制
例 124. 使用 COUNT 查询新的变量
!set plsqlUseSlash true
DECLARE
   I INT
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   I:=V_ORG_VARRAY.LAST()
   V_ORG_VARRAY.EXTEND(2)
   V_ORG_VARRAY(I +1) := 6
   V_ORG_VARRAY(I +2) := 7
   FOR I IN 1..V_ORG_VARRAY.COUNT()
   LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| V(1)=1  |
| V(2)=2  |
| V(3)=3  |
| V(4)=4  |
| V(5)=5  |
| V(6)=6  |
| V(7)=7  |
+---------+
复制
NESTED TABLE
例 125. 使用 EXTEND() 对 NESTED TABLE 变量进行扩展
!set plsqlUseSlash true
DECLARE
   -- 定义一个名为 list_of_names_t 的 table 类型,数据类型为字符串。
   TYPE list_of_names_t IS TABLE OF string
   I INT
   -- 定义一个名为 happyfamily 的 list_of_names_t 变量,并对集合元素进行初始化。
   happyfamily list_of_names_t:=list_of_names_t ()
BEGIN
   -- 给变量 happyfamily 赋值前,为其分配一个大小为 4 的空间,也就是最多可以容纳 4 个元素。
   happyfamily.EXTEND (4)
   -- 依次给变量 happyfamily 赋值
   happyfamily (1) := 'Veva'
   happyfamily (2) := 'Chris'
   happyfamily (3) := 'Eli'
   happyfamily (4) := 'Steven'
   -- 将变量 happyfamily 最后一个元素的下标,赋值给 I。
   I:= happyfamily.LAST()
   -- 使用 extend 方法,给变量 happyfamily 增加两个元素的个数。
   happyfamily.EXTEND (2)
   -- 依次给新增加的元素赋值为 lily,alice。
   happyfamily (I+1) := 'lily'
   happyfamily (I+2) := 'alice'
   -- 使用 count 方法,依次打印出变量 happyfamily 的值。
   FOR l_row IN 1 .. happyfamily.COUNT
   LOOP
      DBMS_OUTPUT.put_line (happyfamily (l_row))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| Veva    |
| Chris   |
| Eli     |
| Steven  |
| lily    |
| alice   |
+---------+
复制

对于 table 变量,由于在赋值前需要用到 EXTEND 方法对变量分配空间,但是如果空间不够,后续可以再增加。

TRIM(k)
  • 使用 TRIM(k) 方法在集合变量的尾部删除最后 k 个条目。

  • 当 k 没有被指定时,即 TRIM(),则删除最后一个条目,已被删除的条目的值将丢失。

  • 使用 TRIM(COUNT()) 方法,则删除集合变量中的全部元素。

  • k 不能大于集合变量的元素的最大个数。

VARRAY
例 126. 使用 TRIM(k) 方法删除部分条目
!set plsqlUseSlash true
DECLARE
   I INT
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   V_ORG_VARRAY.TRIM(2)
   FOR I IN 1..V_ORG_VARRAY.COUNT()
   LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
      END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| V(1)=1  |
| V(2)=2  |
| V(3)=3  |
+---------+
复制
例 127. 使用 TRIM(k) 方法删除全部条目
!set plsqlUseSlash true
DECLARE
   I INT
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   V_ORG_VARRAY.TRIM(V_ORG_VARRAY.COUNT())
   FOR I IN 1..V_ORG_VARRAY.COUNT()
   LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
+---------+
复制
NESTED TABLE
例 128. 使用 TRIM() 对 NESTED TABLE 变量进行缩减
!set plsqlUseSlash true
DECLARE
   -- 定义一个名为 list_of_names_t 的 table 类型,数据类型为字符串。
   TYPE list_of_names_t IS TABLE OF string
   -- 定义一个名为 happyfamily 的 list_of_names_t 变量,并对集合元素进行初始化。
   happyfamily list_of_names_t:=list_of_names_t ()
BEGIN
   -- 给变量 happyfamily 赋值前,为其分配一个大小为 4 的空间,也就是最多可以容纳4个元素。
   happyfamily.EXTEND (4)
   -- 依次给变量 happyfamily 赋值为 vera,chris,eli,steven。
   happyfamily (1) := 'Vera'
   happyfamily (2) := 'Chris'
   happyfamily (3) := 'Eli'
   happyfamily (4) := 'Steven'
   -- 使用 TRIM(2) 方法,删除变量 happyfamily 最后两个元素。
   happyfamily.TRIM(2)
   -- 使用 count 方法,依次打印出变量 happyfamily 的值。
   FOR l_row IN 1 .. happyfamily.COUNT
   LOOP
      DBMS_OUTPUT.put_line (happyfamily (l_row))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| Vera    |
| Chris   |
+---------+
复制
Associative Arrays
例 129. 不能使用 trim() 方法删除 Associative arrays 变量中的元素
!set plsqlUseSlash true
DECLARE
   TYPE numbers_aat IS TABLE OF STRING INDEX BY INT
   l_row INT
   l_numbers numbers_aat
BEGIN
   l_numbers (100) := 'LILY'
   l_numbers (90) := 'GRACE'
   l_numbers (80) := 'ALICE'
   l_numbers (95) := 'LISI'
   l_row:= l_numbers.first()
   l_row:= l_numbers.next(l_row)
   l_numbers.trim(2)
   DBMS_OUTPUT.put_line (l_row||' ' ||l_numbers(l_row))
END;
/
复制

输出结果为:

 EXECUTION FAILED: Task EXEC PLSQL error HiveException: [Error 20357] Error! You can not use TRIM method with an associate array!
*********************************************
ANONYMOUS BLOCK (LINE 12, COLUMN 12, TEXT "l_numbers.trim(2)")
*********************************************
复制
DELETE([k])
  • DELETE(k) 方法,删除集合变量第 k 个条目。

  • 当 k 没有被指定时,即 DELETE(),则删除集合变量中的全部元素。

VARRAY

VARRAY 不支持使用 DELETE(K) 删除集合指定位置的元素。

例 130. 使用 DELETE(K) 方法删除指定条目,将报错
!set plsqlUseSlash true
DECLARE
   I INT;
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING;
   V_ORG_VARRAY ORG_VARRAY_TYPE;
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5');
   V_ORG_VARRAY.DELETE(4);
   FOR I IN 1..V_ORG_VARRAY.COUNT()
   LOOP
      DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I));
   END LOOP;
END;
/
复制

输出结果为:

COMPILE FAILED: Semantic error: [Error 11135]
ANONYMOUS BLOCK (LINE 7, COLUMN 15, TEXT "V_ORG_VARRAY.DELETE(4);"): Wrong number of arguments in call to 'DELETE'
复制
例 131. 使用 DELETE() 方法删除全部条目
!set plsqlUseSlash true
DECLARE
   I INT
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5')
   V_ORG_VARRAY.DELETE()
   FOR I IN 1..V_ORG_VARRAY.COUNT()
   LOOP
   DBMS_OUTPUT.PUT_LINE('V('||I||')=' || V_ORG_VARRAY(I))
   END LOOP;
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
+---------+
复制
NESTED TABLE
例 132. 使用 DELETE(K) 对 NESTED TABLE 变量进行缩减
!set plsqlUseSlash true
DECLARE
   -- 定义一个名为 list_of_names_t 的 table 类型,数据类型为字符串。
   TYPE list_of_names_t IS TABLE OF string
   -- 定义一个名为 happyfamily 的 list_of_names_t 变量,并对集合元素进行初始化。
   happyfamily list_of_names_t:=list_of_names_t ()
BEGIN
   -- 给变量 happyfamily 赋值前,为其分配一个大小为 4 的空间,也就是最多可以容纳 4 个元素。
   happyfamily.EXTEND (4)
   -- 依次给变量 happyfamily 赋值为 vera,chris,eli,steven。
   happyfamily (1) := 'Veva'
   happyfamily (2) := 'Chris'
   happyfamily (3) := 'Eli'
   happyfamily (4) := 'Steven'
   -- 使用 DELETE(2) 方法,删除变量 happyfamily 第 2 个元素。
   happyfamily.DELETE(2)
   -- 使用 count 方法,依次打印出变量 happyfamily 的值。
   FOR l_row IN 1 .. happyfamily.COUNT
   LOOP
   DBMS_OUTPUT.put_line(l_row||','||happyfamily(l_row))
   END LOOP;
END;
/
复制

输出结果为:

+-----------+
|  output   |
+-----------+
| 1,Veva    |
| 2,Eli     |
| 3,Steven  |
+-----------+
复制
Associative Arrays
例 133. 使用 DELETE 方法删除 Associative arrays 变量中的元素
!set plsqlUseSlash true
DECLARE
   TYPE numbers_aat IS TABLE OF STRING INDEX BY INT
   l_row INT
   l_numbers numbers_aat
BEGIN
   l_numbers (100) := 'LILY'
   l_numbers (90) := 'GRACE'
   l_numbers (95) := 'LISI'
   l_numbers (80) := 'ALICE'
   -- 使用 DELETE(80) 方法删除变量 l_numbers 中的第一个,即下标为 80 的元素。
   l_numbers.delete(80)
   -- 将变量 l_numbers 中第一个元素的下标赋值给 l_row。
   l_row:= l_numbers.first()
   -- 将变量 l_numbers 中第一个元素的后一个元素的下标赋值给 l_row。
   l_row:= l_numbers.NEXT(l_row)
   -- 输出变量 l_numbers 中第一个元素的后一个元素的下标,及其所对应的值。
   DBMS_OUTPUT.put_line (l_row||' ' ||l_numbers(l_row))
END;
/
复制

输出结果为:

+----------+
|  output  |
+----------+
| 95 LISI  |
+----------+
复制

可以看到,最初变量 l_numbers 的第一个元素为 80,在删除掉第一个元素之后,变量 l_numbers 的第一个元素的后一个元素的下标,也相应发生了变化。

EXISTS()

判断第 i 位是否存在,如果存在则返回 true,不存在则返回 false。

VARRAY
例 134. 使用 EXISTS() 方法,查询 VARRAY 变量中第 2 行的数据是否存在
!set plsqlUseSlash true
DECLARE
   -- 定义一个布尔类型的变量为 l。
   l boolean
   -- 声明一个能保存 10 个 STRING 数据类型的成员的 VARRAY 数据类型 ORG_VARRAY_TYPE。
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   -- 定义一个 ORG_VARRAY_TYPE 类型的 VARRAY 变量 V_ORG_VARRAY。
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   -- 依次给变量 V_ORG_VARRAY 赋值。
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','1','3','4','5')
   -- 使用 EXISTS() 方法方法,判断变量 V_ORG_VARRAY 第二个元素是否存在,并赋值给 l。
   l:=V_ORG_VARRAY.exists(2)
   -- 输出变量 l 的值。
   DBMS_OUTPUT.PUT_LINE(l)
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| TRUE    |
+---------+
复制
Associative Arrays
例 135. 使用 EXISTS() 方法,查询 Associative Arrays 变量中 key 为 95 的元素是否存在
-- 输出变量 l 的值。
!set plsqlUseSlash true
DECLARE
   TYPE numbers_aat IS TABLE OF STRING INDEX BY INT
   l_row INT
   -- 定义一个布尔类型的变量为 l。
   l boolean
   l_numbers numbers_aat
BEGIN
   l_numbers (100) := 'LILY'
   l_numbers (90) := 'GRACE'
   l_numbers (80) := 'ALICE'
   l_numbers (95) := 'LISI'
   -- 使用 EXISTS() 方法方法,判断变量 l_numbers 中是否存在 key 等于 95 的元素,并赋值给 l。
   l := l_numbers.exists(95)
   DBMS_OUTPUT.put_line (l)
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| TRUE    |
+---------+
复制
LIMIT()

对于 VARRAY 类型,返回声明类型时,所定义的最大容量,在 Inceptor 中会返回 null 值。

例 136. Inceptor 中对变量 VARRAY 使用 LIMIT() 方法,会报出 null 值
!set plsqlUseSlash true
DECLARE
   l INT
   TYPE ORG_VARRAY_TYPE IS VARRAY(10) OF STRING
   V_ORG_VARRAY ORG_VARRAY_TYPE
BEGIN
   V_ORG_VARRAY := ORG_VARRAY_TYPE('1','2','3','4','5','6','7','8','9','10')
   l:=V_ORG_VARRAY.limit()
   DBMS_OUTPUT.PUT_LINE(l)
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| null    |
+---------+
复制
例 137. Inceptor 中对变量 NESTED TABLE 使用 LIMIT() 方法,会报出 null 值
!set plsqlUseSlash true
DECLARE
   l INT
   TYPE list_of_names_t IS TABLE OF string
   happyfamily list_of_names_t:=list_of_names_t ()
BEGIN
   happyfamily.EXTEND(4)
   happyfamily (1) := 'Veva'
   happyfamily (2) := 'Chris'
   happyfamily (3) := 'Eli'
   happyfamily (4) := 'Steven'
   l:=happyfamily.limit()
   DBMS_OUTPUT.PUT_LINE(l)
END;
/
复制

输出结果为:

+---------+
| output  |
+---------+
| null    |
+---------+
复制