PLSQL基礎知識點總結 (2)

PLSQL中提供了三種數據的形式,功能還是比較強大的。但是總的來說,PLSQL中的數組知識掌握最簡單的那種,其他大致瞭解就可以了。因爲從實際應用的角度來說,在PLSQL中用到數組的機率不是很大。這主要是由於PLSQL跟數據庫的緊密結合特性所決定的,數據庫的表可以很輕易得實現基本的數組功能。當然這是我個人的一點理解,不一定正確。下面是詳細介紹
 
 
1、PLSQL中的數組共分三類:
 
I  - 嵌套表(Nested tables)

TYPEnested_typeISTABLEOFVARCHAR2 ( 30 ) [not null];

--值爲varchar2的數組,下標爲默認int

特徵:可刪除信息,下標不變
 
II - 變長數組(Variable-SizedArrays)

TYPECalendarISVARRAY(366 ) OFNUMBER;

--366number數組,下標1-366( 不是 0-365)

特徵:一般在可預知數組個數的情況下使用,類似其他語言的Array
 
III- 索引表(Associative Array)

TYPEpopulation_typeISTABLEOFNUMBER

INDEXBYVARCHAR2( 64 );

--下標是varchar2,值是number 的數組

特徵:可使用不連續數字、負數、字符作爲下標,長度大小可變
      在創建數組時便分配內存,無需之後申請
      index by 只能跟BINARY_INTEGERPLS_INTEGERVARCHAR2三種類型
 
 
2、數組中的賦值錯誤問題:

 

DECLARE

 TYPEwordlistISTABLEOFVARCHAR2 ( 5 );

 words wordlist;

BEGIN

 words( 1 )      := 10; --COLLECTION_IS_NULL,未賦空間

 words         := wordlist(10, 20 , 30 ); --進行賦值

 words( 1 )      := 'yes'; --正確

 words( 2 )      := words( 1 ) || 'no';--正確

 words( 3 )      := 'longer than 5 characters';--VALUE_ERROR,字符過長

 words( 'B' )    := 'dunno'; --VALUE_ERROR,下標錯誤

 words( 4 )      := 'maybe'; --SUBSCRIPT_BEYOND_COUNT,下標超限

END;

 
在聲明words wordlist; 之後數組未初始化,完全沒有用處
必須進行初始化,如:
words := wordlist(10,20 , 30 );--定值初始化;
words := wordlist();--空值初始化,任何數組必須先初始化;
words.extend(n);--末尾增加N位空間,不加N則爲默認增加1位;
然後可以賦值
 
 
3、數組相關集合函數:
 
1、EXISTS(判斷第i位是否存在)

IFcourses.EXISTS(i)THEN

 courses(i)    := new_course;

ENDIF;

 

2、COUNT(數組中的元素個數)

FORiIN1.. courses.COUNTLOOP...

注意:COUNT會忽略已經被刪除的元素

 

3、LIMIT(集合的最大容量)

IF(projects.COUNT +15) < projects.LIMITTHEN...

注意:LIMIT一般只對變長數組有效(其他兩類均返回NULL)
 
4、FIRST和LAST(第一個和最後一個元素的下標)

FORiINcourses.FIRST .. courses.LASTLOOP...

注意:返回值是下標,而不是值!在遍歷元素時,FIRST和LAST都會忽略被刪除的元素
 
5、PRIOR和NEXT(返回索引爲n的前驅/後驅下標)

n := courses.PRIOR(courses.FIRST); --assigns NULL to n

注意:返回值是下標,而不是值!在遍歷元素時,FIRST和LAST都會忽略被刪除的元素
 
6、EXTEND(擴大集合容量)

courses.EXTEND(m,n ); --將第n個元素的值複製m份加到集合末端

注意:m默認爲1,n默認爲null,m包含被刪除元素
 
7、TRIM(縮減集合容量)

courses.TRIM(3);--extend相反

 
8、DELETE(刪除集合元素)

courses.DELETE     --刪除全部

courses.DELETE(2)  --刪除第2個元素

courses.DELETE(2,5 ) --刪除第2到第5 個元素

注意:使用delete的時候必須要結合3中數組的不同特徵!
 
 
4、Exception的類型及原因:
 

COLLECTION_IS_NULL       ---調用一個空集合的方法,集合未被初始化

NO_DATA_FOUND              ---下標索引指向一個被刪除的元素,或是關聯數組中不存在的元素

SUBSCRIPT_BEYOND_COUNT  ---下標索引值超過集合中的元素個數

SUBSCRIPT_OUTSIDE_LIMIT---下標索引超過允許範圍之外

VALUE_ERROR                 ---下標索引值爲空,或是不是指定的下標類型

 
 
5、關於數組的特有批量綁定ForAll
 
1、語法結構:

 

FORALLiINpnums.FIRST .. pnums.LAST

INSERTINTOpartnoVALUES(pnums(i));  ---注意:不用再Loop

 
 
2、可使用%BULK_ROWCOUNT屬性來計算FORALL語句所影響到的行數

 

IFSQL%BULK_ROWCOUNT ( 3 ) = 0THEN...

 

表示如果第3次操作沒有對數據影響的行數爲0話……

注意%BULK_ROWCOUNT的值是可以大於1的,比如批量插入等

 
3、使用%BULK_EXCEPTIONS屬性來控制FORALL異常

 

DECLARE

 TYPEnumlistISTABLEOFNUMBER ;

 

 num_tab      numlist  := numlist(10,0,11,12,30,0,20,199,2,0,9,1);

 ERRORS      NUMBER;

 dml_errors   EXCEPTION;

 PRAGMAEXCEPTION_INIT(dml_errors, -24381 );

BEGIN

 FORALLiINnum_tab.FIRST .. num_tab.LASTSAVEEXCEPTIONS

   DELETEFROMemp

         WHEREsal >500000/ num_tab(i);

EXCEPTION

 WHENdml_errorsTHEN

   ERRORS   :=SQL%BULK_EXCEPTIONS.COUNT;

   DBMS_OUTPUT.put_line('Number of errors is '|| ERRORS);

 

   FORiIN1..ERRORSLOOP

     DBMS_OUTPUT.put_line(  'Error '

                          || i

                          ||' occurred during '

                          ||'iteration '

                          ||SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);

     DBMS_OUTPUT.put_line(  'Oracle error is '

                          ||SQLERRM(-SQL% BULK_EXCEPTIONS (i).ERROR_CODE));

   ENDLOOP;

END;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章