codecamp

PL / SQL集合

集合是具有相同的数据类型元素的有序组。每个元件由一个唯一的标表示其集合中的位置识别。

PL / SQL提供了三种集合类型:

  • 索引表或关联数组

  • 嵌套表

  • 可变大小的数组或VARRAY

Oracle文档提供了用于每种类型的集合的以下特征:

集合类型元素的数量标型密集或稀疏其中,创建它可以是object类型属性
关联数组(或索引表) 无界字符串或整数只有在PL / SQL块没有
嵌套表无界整数启动密集,可以变得稀疏无论是在PL / SQL块或模式级
可变大小的数组(VARRAY) 有界整数始终致密无论是在PL / SQL块或模式级

我们章节“PL / SQL阵列”中已经讨论过变长数组。在本章中,我们将讨论PL / SQL表。

这两种类型的PL / SQL表,即,索引表和嵌套表的有相同的结构和它们的行所使用的下标符号访问。然而,这两种类型的表在一个方面不同;嵌套表可以存储在数据库中列和索引表不能。

索引表

一个索引表(也称为关联数组)是一组键-值对。每个键是唯一的,并且用于定位对应的值。键可以是整数或字符串。

一个索引表是使用以下语法创建。在这里,我们正在创建一个索引表名为TABLE_NAME,它的键会subscript_type和相关的值将ELEMENT_TYPE

TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY subscript_type;

table_name type_name;

例:

下面的示例演示如何创建一个表来存储整数值与名称一起,后来它打印的名称相同的列表。

DECLARE
   TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2(20);
   salary_list salary;
   name   VARCHAR2(20);
BEGIN
   -- adding elements to the table
   salary_list('Rajnish')  := 62000;
   salary_list('Minakshi')  := 75000;
   salary_list('Martin') := 100000;
   salary_list('James') := 78000;

   -- printing the table
   name := salary_list.FIRST;
   WHILE name IS NOT null LOOP
      dbms_output.put_line
      ('Salary of ' || name || ' is ' || TO_CHAR(salary_list(name)));
      name := salary_list.NEXT(name);
   END LOOP;
END;
/

当上述代码在SQL提示符执行时,它产生了以下结果:

Salary of James is 78000
Salary of Martin is 100000
Salary of Minakshi is 75000
Salary of Rajnish is 62000

PL/SQL procedure successfully completed.

例:

一个索引表的元素也可以是任何数据库表字段中的任何数据库表或%TYPE的ROWTYPE%。下面的例子说明了这个概念。我们将使用存储在我们的数据库CUSTOMERS表:

Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
+----+----------+-----+-----------+----------+
DECLARE
   CURSOR c_customers is
      select  name from customers;
   
   TYPE c_list IS TABLE of customers.name%type INDEX BY binary_integer;
   name_list c_list;
   counter integer :=0;
BEGIN
   FOR n IN c_customers LOOP
      counter := counter +1;
      name_list(counter)  := n.name;
      dbms_output.put_line('Customer('||counter|| '):'||name_list(counter));
  END LOOP;
END;
/

当上述代码在SQL提示符执行时,它产生了以下结果:

Customer(1): Ramesh 
Customer(2): Khilan 
Customer(3): kaushik    
Customer(4): Chaitali 
Customer(5): Hardik 
Customer(6): Komal

PL/SQL procedure successfully completed

嵌套表

嵌套表是像元件的任意数量的一维数组。然而,嵌套表不同于在以下几个方面的数组:

  • 数组元素有一个申报号,但嵌套表没有。嵌套表的大小可以动态地增加。

  • 数组始终是茂密的,也就是说,它总是有连续的下标。嵌套数组是密集最初,但当元素从它删除,它可以变得稀疏。

嵌套表是使用以下语法创建的:

TYPE type_name IS TABLE OF element_type [NOT NULL];

table_name type_name;

这个声明是类似于索引表的声明,但没有索引BY子句。

嵌套表可以存储在数据库列,所以它可用于简化在那里你加入一个较大的表中的单个列的表的SQL操作。关联数组不能存储在数据库中。

例:

以下实施例说明使用嵌套表:

DECLARE
   TYPE names_table IS TABLE OF VARCHAR2(10);
   TYPE grades IS TABLE OF INTEGER;

   names names_table;
   marks grades;
   total integer;
BEGIN
   names := names_table('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz');
   marks:= grades(98, 97, 78, 87, 92);
   total := names.count;
   dbms_output.put_line('Total '|| total || ' Students');
   FOR i IN 1 .. total LOOP
      dbms_output.put_line('Student:'||names(i)||', Marks:' || marks(i));
   end loop;
END;
/

当上述代码在SQL提示符执行时,它产生了以下结果:

Total 5 Students
Student:Kavita, Marks:98
Student:Pritam, Marks:97
Student:Ayan, Marks:78
Student:Rishav, Marks:87
Student:Aziz, Marks:92

PL/SQL procedure successfully completed.

例:

嵌套表的元素也可以是任何数据库表字段中的任何数据库表或%TYPE的ROWTYPE%。下面的例子说明了这个概念。我们将使用存储在我们的数据库CUSTOMERS表:

Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
+----+----------+-----+-----------+----------+
DECLARE
   CURSOR c_customers is 
      SELECT  name FROM customers;

   TYPE c_list IS TABLE of customers.name%type;
   name_list c_list := c_list();
   counter integer :=0;
BEGIN
   FOR n IN c_customers LOOP
      counter := counter +1;
      name_list.extend;
      name_list(counter)  := n.name;
      dbms_output.put_line('Customer('||counter||'):'||name_list(counter));
   END LOOP;
END;
/

当上述代码在SQL提示符执行时,它产生了以下结果:

Customer(1): Ramesh 
Customer(2): Khilan 
Customer(3): kaushik    
Customer(4): Chaitali 
Customer(5): Hardik 
Customer(6): Komal

PL/SQL procedure successfully completed.

收集方法

PL / SQL提供了内置的收集方法,使藏品更容易使用。下表列出的方法和它们的用途:

SN 方法名称及用途
1 EXISTS(N)
如果集合中的第n个元素存在,则返回TRUE;否则返回FALSE。
2 计数
返回集合当前包含的元素数量。
3 限制
检查集合的最大尺寸。
4 第一
返回使用整数下标集合中的第一个(最小的)索引编号。
持续
返回使用整数下标集合中的最后一个(最大的)索引编号。
6 PRIOR(N)
返回一集合中之前指数n的索引号。
7 NEXT(N)
返回成功指数n的索引号。
8 延伸
追加到一个集合了一个null元素。
9 扩展(N)
ñ追加空元素的集合。
10 扩展(N,I)
追加的第i个元素集合的n个拷贝。
11 修剪
移除一个集合的末尾一个元素。
12 TRIM(N)
移除一个集合的末尾n个元素。
13 删除
移除一个集合的所有元素,设置计数为0。
14 DELETE(N)
移除用数字键或嵌套表的关联数组的第n个元素。如果关联数组有一个字符串键,对应于该键值的元素将被删除。如果n为空,DELETE(N)什么都不做。
15 DELETE(M,N)
移除关联数组或嵌套表范围m..n所有元素。如果m大于n或如果m大于或n是零,DELETE(M,N)什么也不做。

收藏例外

下表提供的收集异常和当它们被提出:

收集异常募集情况
COLLECTION_IS_NULL 您尝试在一个原子集合空操作。
没有找到数据下标表示被删除的元素,或关联数组的元素不存在。
SUBSCRIPT_BEYOND_COUNT 下标超过了集合中的元素的数量。
SUBSCRIPT_OUTSIDE_LIMIT 下标允许的范围之内。
VALUE_ERROR 下标为空或不可转换的关键类型。如果该键被定义为PLS_INTEGER范围可能发生这种异常,下标是在该范围之外。

PL / SQL循环
PL / SQL字符串
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }