📅  最后修改于: 2020-11-26 06:01:55             🧑  作者: Mango
在本章中,我们将讨论PL / SQL中的集合。集合是具有相同数据类型的元素的有序组。每个元素由代表其在集合中位置的唯一下标标识。
PL / SQL提供了三种收集类型-
Oracle文档为每种类型的集合提供以下特征-
Collection Type | Number of Elements | Subscript Type | Dense or Sparse | Where Created | Can Be Object Type Attribute |
---|---|---|---|---|---|
Associative array (or index-by table) | Unbounded | String or integer | Either | Only in PL/SQL block | No |
Nested table | Unbounded | Integer | Starts dense, can become sparse | Either in PL/SQL block or at schema level | Yes |
Variablesize array (Varray) | Bounded | Integer | Always dense | Either in PL/SQL block or at schema level | Yes |
我们已经在“ PL / SQL数组”一章中讨论了varray。在本章中,我们将讨论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.
索引表的元素也可以是任何数据库表的%ROWTYPE或任何数据库表字段的%TYPE 。以下示例说明了该概念。我们将使用存储在数据库中的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_lis t(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;
此声明类似于索引表的声明,但是没有INDEX 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.
嵌套表的元素也可以是任何数据库表的%ROWTYPE或任何数据库表字段的%TYPE。以下示例说明了该概念。我们将使用存储在数据库中的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.No.ame%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提供了使收集更易于使用的内置收集方法。下表列出了方法及其用途-
S.No | Method Name & Purpose |
---|---|
1 |
EXISTS(n) Returns TRUE if the nth element in a collection exists; otherwise returns FALSE. |
2 |
COUNT Returns the number of elements that a collection currently contains. |
3 |
LIMIT Checks the maximum size of a collection. |
4 |
FIRST Returns the first (smallest) index numbers in a collection that uses the integer subscripts. |
5 |
LAST Returns the last (largest) index numbers in a collection that uses the integer subscripts. |
6 |
PRIOR(n) Returns the index number that precedes index n in a collection. |
7 |
NEXT(n) Returns the index number that succeeds index n. |
8 |
EXTEND Appends one null element to a collection. |
9 |
EXTEND(n) Appends n null elements to a collection. |
10 |
EXTEND(n,i) Appends n copies of the ith element to a collection. |
11 |
TRIM Removes one element from the end of a collection. |
12 |
TRIM(n) Removes n elements from the end of a collection. |
13 |
DELETE Removes all elements from a collection, setting COUNT to 0. |
14 |
DELETE(n) Removes the nth element from an associative array with a numeric key or a nested table. If the associative array has a string key, the element corresponding to the key value is deleted. If n is null, DELETE(n) does nothing. |
15 |
DELETE(m,n) Removes all elements in the range m..n from an associative array or nested table. If m is larger than n or if m or n is null, DELETE(m,n) does nothing. |
下表提供了收集异常及其引发时间-
Collection Exception | Raised in Situations |
---|---|
COLLECTION_IS_NULL | You try to operate on an atomically null collection. |
NO_DATA_FOUND | A subscript designates an element that was deleted, or a nonexistent element of an associative array. |
SUBSCRIPT_BEYOND_COUNT | A subscript exceeds the number of elements in a collection. |
SUBSCRIPT_OUTSIDE_LIMIT | A subscript is outside the allowed range. |
VALUE_ERROR | A subscript is null or not convertible to the key type. This exception might occur if the key is defined as a PLS_INTEGER range, and the subscript is outside this range. |