PL/SQL 集合

2021-08-30 15:52 更新

在本章中,我們將討論PL/SQL中的集合。集合是具有相同數(shù)據(jù)類型的有序元素組。 每個元素都由一個唯一的下標來表示它在集合中的位置。

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

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

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

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

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

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

索引表

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

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

table_name type_name;
SQL

示例

以下示例顯示了如何創(chuàng)建一個表來存儲整數(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 過程已成功完成。
Shell

示例2

索引表的元素也可以是任何數(shù)據(jù)庫表的%ROWTYPE或任何數(shù)據(jù)庫表字段的%TYPE。 以下示例說明了這個概念。我們將使用存儲在數(shù)據(jù)庫中的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

存儲過程代碼如下 -

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é)果 -


嵌套表

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

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

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

TYPE type_name IS TABLE OF element_type [NOT NULL]; 

table_name type_name;
SQL

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

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

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

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

當上面的代碼在SQL提示符下執(zhí)行時,它會產(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 過程已成功完成。
Shell

示例2

嵌套表的元素也可以是任何數(shù)據(jù)庫表的%ROWTYPE或任何數(shù)據(jù)庫表字段的%TYPE。以下示例說明了這個概念。我們將使用存儲在數(shù)據(jù)庫中的CUSTOMERS表,參考以下代碼的實現(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)置的集合方法,使集合更易于使用。下表列出了方法及其用途 -

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

集合異常

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

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

 




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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號