PL/SQL 集合

2021-08-30 15:52 更新

在本章中,我們將討論P(yáng)L/SQL中的集合。集合是具有相同數(shù)據(jù)類型的有序元素組。 每個(gè)元素都由一個(gè)唯一的下標(biāo)來(lái)表示它在集合中的位置。

PL/SQL提供了三種集合類型 -

  • 索引表或關(guān)聯(lián)數(shù)組
  • 嵌套的表
  • 可變大小的數(shù)組或Varray類型

Oracle的每種類型的集合有以下特征 -

集合類型 元素個(gè)數(shù) 下標(biāo)類型 密集或稀疏 在哪創(chuàng)建 是否為對(duì)象類型屬性
關(guān)聯(lián)數(shù)組(或索引表) 無(wú)界 字符串或整數(shù) 任意一種 只在PL/SQL塊中 No
嵌套表 無(wú)界 整數(shù) 開始密集,可以變得稀疏 在PL/SQL塊或模式級(jí)別 Yes
可變大小數(shù)組(Varray) 有界 整數(shù) 總是密集 在PL/SQL塊或模式級(jí)別 Yes

我們已經(jīng)在“PL/SQL數(shù)組”一章中討論了varray。 在本章中,將討論P(yáng)L/SQL表。

兩種類型的PL/SQL表(即索引表和嵌套表)具有相同的結(jié)構(gòu),并且使用下標(biāo)符號(hào)來(lái)訪問(wèn)它們的行。 但是,這兩種表在一個(gè)方面有所不同, 嵌套表可以存儲(chǔ)在數(shù)據(jù)庫(kù)列中,索引表不能。

索引表

索引表(也稱為關(guān)聯(lián)數(shù)組)是一組鍵 - 值對(duì)。 每個(gè)鍵都是唯一的,用來(lái)定位相應(yīng)的值。鍵可以是整數(shù)或字符串。使用以下語(yǔ)法創(chuàng)建索引表。 在這里,正在創(chuàng)建一個(gè)名為table_name的索引表,其中的鍵是subscript_type,關(guān)聯(lián)的值是element_type,參考以下語(yǔ)法 -

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

table_name type_name;
SQL

示例

以下示例顯示了如何創(chuàng)建一個(gè)表來(lái)存儲(chǔ)整數(shù)值以及名稱,然后打印出相同的名稱列表。

SET SERVEROUTPUT ON SIZE 99999;
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

執(zhí)行上面示例代碼,得到以下結(jié)果 -

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

PL/SQL 過(guò)程已成功完成。
Shell

示例2

索引表的元素也可以是任何數(shù)據(jù)庫(kù)表的%ROWTYPE或任何數(shù)據(jù)庫(kù)表字段的%TYPE。 以下示例說(shuō)明了這個(gè)概念。我們將使用存儲(chǔ)在數(shù)據(jù)庫(kù)中的CUSTOMERS表及數(shù)據(jù) -

CREATE TABLE CUSTOMERS( 
   ID   INT NOT NULL, 
   NAME VARCHAR (20) NOT NULL, 
   AGE INT NOT NULL, 
   ADDRESS CHAR (25), 
   SALARY   DECIMAL (18, 2),        
   PRIMARY KEY (ID) 
);
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 );  

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 );  

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (3, 'kaushik', 23, 'Kota', 2000.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (4, 'Chaitali', 25, 'Mumbai', 6500.00 ); 

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (5, 'Hardik', 27, 'Bhopal', 8500.00 );  

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) 
VALUES (6, 'Komal', 22, 'MP', 4500.00 );
SQL

存儲(chǔ)過(guò)程代碼如下 -

SET SERVEROUTPUT ON SIZE 99999;
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

執(zhí)行上面示例代碼,得到以下結(jié)果 -


嵌套表

嵌套表就像一個(gè)具有任意數(shù)量元素的一維數(shù)組。但是,嵌套表與數(shù)組在以下幾個(gè)方面不同 -

  • 數(shù)組是一個(gè)有聲明數(shù)量的元素集合,但是一個(gè)嵌套的表沒有。嵌套表的大小可以動(dòng)態(tài)增加。
  • 數(shù)組總是密集的,即它總是具有連續(xù)的下標(biāo)。 嵌套數(shù)組最初是密集的,但是當(dāng)從其中刪除元素時(shí),它可能變得稀疏。

使用以下語(yǔ)法創(chuàng)建嵌套表 -

TYPE type_name IS TABLE OF element_type [NOT NULL]; 

table_name type_name;
SQL

這個(gè)聲明類似于索引表的聲明,只是沒有INDEX BY子句。

嵌套表可以存儲(chǔ)在數(shù)據(jù)庫(kù)列中。 它可以進(jìn)一步用于簡(jiǎn)化SQL操作,您可以使用更大的表來(lái)連接單列表。關(guān)聯(lián)數(shù)組不能存儲(chǔ)在數(shù)據(jù)庫(kù)中。

示例1下面的例子說(shuō)明了嵌套表的使用 -

SET SERVEROUTPUT ON SIZE 99999;
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

當(dāng)上面的代碼在SQL提示符下執(zhí)行時(shí),它會(huì)產(chǎn)生以下結(jié)果 -

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 過(guò)程已成功完成。
Shell

示例2

嵌套表的元素也可以是任何數(shù)據(jù)庫(kù)表的%ROWTYPE或任何數(shù)據(jù)庫(kù)表字段的%TYPE。以下示例說(shuō)明了這個(gè)概念。我們將使用存儲(chǔ)在數(shù)據(jù)庫(kù)中的CUSTOMERS表,參考以下代碼的實(shí)現(xiàn) -

SET SERVEROUTPUT ON SIZE 99999;
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

執(zhí)行上面示例代碼,得到以下結(jié)果 -


集合方法

PL/SQL提供了內(nèi)置的集合方法,使集合更易于使用。下表列出了方法及其用途 -

編號(hào) 方法 目的
1 EXISTS(n) 如果集合中的第n個(gè)元素存在,則返回TRUE; 否則返回FALSE。
2 COUNT 返回集合當(dāng)前包含的元素的數(shù)量。
3 LIMIT 檢查集合的最大容量(大小)。
4 FIRST 返回使用整數(shù)下標(biāo)的集合中的第一個(gè)(最小)索引編號(hào)。
5 LAST 返回使用整數(shù)下標(biāo)的集合中的最后(最大)索引編號(hào)。
6 PRIOR(n) 返回集合中索引n之前的索引編號(hào)。
7 NEXT(n) 返回索引n成功的索引號(hào)。
8 EXTEND 追加一個(gè)空(null)元素到集合。
9 EXTEND(n) n個(gè)空(null)元素追加到集合中。
10 EXTEND(n,i) 將第i個(gè)元素的n個(gè)副本追加到集合中。
11 TRIM 刪除一個(gè)集合末尾的元素。
12 TRIM(n) 刪除集合末尾的n個(gè)元素。
13 DELETE 刪除集合中的所有元素,將COUNT設(shè)置為0。
14 DELETE(n) 使用數(shù)字鍵或嵌套表從關(guān)聯(lián)數(shù)組中刪除第n個(gè)元素。 如果關(guān)聯(lián)數(shù)組有一個(gè)字符串鍵,則刪除鍵值對(duì)應(yīng)的元素。 如果n為空,則DELETE(n)不執(zhí)行任何操作。
15 DELETE(m,n) 從關(guān)聯(lián)數(shù)組或嵌套表中移除m..n范圍內(nèi)的所有元素。 如果m大于n,或者mn為空,則DELETE(m,n)將不執(zhí)行任何操作。

集合異常

下表提供了集合異常情況以及何時(shí)引發(fā) -

編號(hào) 集合異常 引發(fā)的情況
1 COLLECTION_IS_NULL 嘗試在一個(gè)原子空集合上進(jìn)行操作。
2 NO_DATA_FOUND 下標(biāo)指定被刪除的元素或關(guān)聯(lián)數(shù)組中不存在的元素。
3 SUBSCRIPT_BEYOND_COUNT 下標(biāo)超出了集合中元素的數(shù)量。
4 SUBSCRIPT_OUTSIDE_LIMIT 下標(biāo)超出允許的范圍。
5 VALUE_ERROR 下標(biāo)為空或不能轉(zhuǎn)換為鍵類型。如果鍵定義為PLS_INTEGER范圍,并且下標(biāo)超出此范圍,則可能會(huì)發(fā)生此異常。

 




以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)