在PL/SQL塊中可以定義變數和數據類型,這使得PL/SQL塊對數據的處理更加靈活。 變數和類型的定義放在PL/SQL塊的變數聲明部分。 變數的定義與使用 變數的定義有兩種格式,分別為:變數名 類型 [約束][DEFAULT 預設值]變數名 類型[約束][:=初始值]其中用方括弧限定的部分是可選的。 ...
在PL/SQL塊中可以定義變數和數據類型,這使得PL/SQL塊對數據的處理更加靈活。
變數和類型的定義放在PL/SQL塊的變數聲明部分。
變數的定義與使用
變數的定義有兩種格式,分別為:
變數名 類型 [約束][DEFAULT 預設值]
變數名 類型[約束][:=初始值]
其中用方括弧限定的部分是可選的。
約束用來規定變數必須滿足的條件,比如“ NOTNULL”約束指定變數不能為空值,這樣在定義變數的時候就要為其指定初始值或預設值。
變數名要遵守一定的命名規則。
變數名必須以字母開頭,包含數字、字母、下劃線以反$、#符號,長度不能超過30字元,並且不能與Oracle關鍵字相同。
變數名與大小寫是無關的。
變數的類型可以是PL/SQL提供的數據類型,也可以是用戶自定義的類型。
基本的數據類型 說明
BINARY INTEGER 整數類型的數據 (註:BINARY 二進位)
NUMBER[(精度,小數)] 可表示整數和浮點數
CHAR [(最大長度)] 字元串,長度可達32 767位元組
LONG 長字元串
LONG RAW 與資料庫中的LONG RAW -致
VARCHAR2 (最大長度) 與資料庫中的VARCHAR2一致
DATE 與資料庫中的DATE-致
BOOLEAN 取值為TRUE和FALSE
除了上述基本類型外, PL/SQL還定義了一些子類型。
在PL/SQL塊中既可以使用這些基本數據類型,也可以使用它們的子類型,但數據的最終類型仍然是它的基本類型。
子類型 父類型 說明
NATURAL與NATURALN BINARY INTEGER 自然數,其中後者不能為空
POSITIVE與POSITIVEN BINARY INTEGER 正整數,其中後者不能為空
SIGNTYPE BINARY INTEGER 可取值為 1 、0 、1
INT與INTEGER BINARY INTEGER 整數型數據
DEC 、DECIMAL NUMERIC BINARY INTEGER 等價於NUMBER ,提供了ANSI相容性
FLOAT BINARY INTEGER 126位二進位的浮點數
REAL BINARY INTEGER 63位二進位的浮點數
CHARACTER CHAR 與CHAR等價,提供了ANSI相容性
STRING VARCHAR2 與VARCHAR2等價,提供了ANSI相容性
VARCHAR VARCHAR2 與VARCHAR2等價
變數在定義時可以指定預設值或初始值,在PL/SQL塊的運行過程中還可以為其賦值。
賦值的格式為:
變數名:=表達式
如果需要輸出變數的值,則要調用DBMS_OUTPUT程式包中的過程PUT_LINE ,這個過程的參數是要輸出的變數或表達式。
除了變數的聲明外,變數的賦值、輸出等操作都要放在PL/SQL塊的可執行部分。
下麵的代碼演示了變數的聲明、賦值和輸出操作。
DECLARE
id integer NOT NULL DEFAULT 100;
name varchar2(20) := 'SMITH';
birthday date DEFAULT SYSDATE;
BEGIN
id := 200;
dbms_output.put_line('id的值為:'||id);
dbms_output.put_line('name的值為:'||name);
dbms_output.put_line('birthday的值為:'||birthday);
END;
在輸出變數之前,要確保SQL*Plus的輸出是打開的,否則將得不到輸出結果。
也就是說,首先要在SQL*Plus中對參數SERVEROUTPUT進行設置:
SET SERVEROUTPUT ON
PL/SQL塊的代碼可以直接在“ SQL>"提示符下輸入。
輸入結束後,執行命令“/”即可使該PL/SQL塊開始執行。
如某發現代碼執行時有錯誤,可以輸入“ ed ”命令進行修改。
通過“ ed ”命令將打開一個文本編輯器,對緩衝區中的內容進行編輯。
編輯完後重新輸入命令“/”,可以再次執行PL/SQL塊。
在定義變數時,除了直接為變數指定類型外,還可以通過%TYPE 屬性為變數指定類型, o/oTYPE用於獲得另一個變數或者表中某個列的類型,使得新定義的變數與該變數或該列的類型完全一致。
%TYPE屬性的用法為:
變數名 另一變數%TYPE
變數名 表.列%TYPE
使用%TYPE屬性的一個好處是當原來的變數或列的類型被修改後,不需要修改新變數的類型。
另一個好處是,我們只希望一個變數與另一個變數的類型相同,但是我們可以不關心它到底是什麼類型。
例如:
id integer NOT NULL DEFAULT 100;
name varchar2(20) := 'SMITH';
birthday date DEFAULT SYSDATE;
age id%type := 200;
sex emp.empno%type;
註:本例中變數age與變數ID類型相同,這裡包括約束NOT NULL,所以要為變數age指定初始值或者預設值。
而變數sex引用表中列的類型,如果此列有約束,變數sex並未有此約束。
如何在PL/SQL中定義類型
用戶可以在PL/SQL塊中根據需要定義數據類型,然後利用這個類型定義變數。
常用的自定義類型包括記錄類型和集合類型,它們都是複合數據類型。
記錄類型允許在一個類型中包含若幹類型不同的欄位,欄位類型可以是基本數據類型,也可以是另一個複合數據類型。
記錄類型的定義格式為:
TYPE 類型名 IS RECORD
(欄位1 定義,
欄位2 定義,
··
);
其中每個欄位的定義都與變數定義的方法完全相同,即包括欄位名、類型、約束、預設值或初始值等幾部分。
例如,要存儲學生的信息,可以定義一個記錄類型,包括姓名、年齡、學號、成績等欄位。
該記錄的定義為:
TYPE student IS RECORD
(name char(10),
age integer DEFAULT 20,
no char(10),
score number(5,2)
);
定義了記錄類型後,現在就可以定義該類型的變數了。
例如,下麵的代碼定義了兩個
student類型的變數,分別表示兩個學生。
stu1 student;
stu2 student;
在使用記錄類型變數時,要單獨引用它的每個欄位,引用的方法為:
變數.欄位
記錄型變數中欄位的使用方法與普通變數基本相同,可以為其賦值,也可以輸出它的值。
下麵的代碼是在定義上述類型和變數的基礎上,某個PL/SQL塊的可執行部分:
BEGIN
stu1.name := 'smith';
stu1.no := '0203001';
stu1.score := 97;
dbms_output.put_line(stu1.name);
dbms_output.put_line ( stu1.no);
dbms_output.put_line(stu1.score);
END;
定義記錄類型變數的另外一個簡便方法是使用表的%ROWTYPE屬性。
%ROWTYPE屬性可以取得表中各個欄位的定義,使得記錄類型變數的結構與表中一行的結構完全一致。
例如,
根據emp表的結構可以定義記錄類型變數employee:
employee emp%rowtype;
這樣就定義了一個記錄類型變數employee ,它所包含的欄位及其類型、長度與表emp的各列完全相同。
在PL/SQL塊中可以直接使用這個變數的各個欄位,例如:
BEGIN
employee.empno := 100;
employee.ename :='SMITH' ;
dbms_output.put_line(employee.empno);
dbms_output.put_line(employee.ename);
END;
使用%ROWTYPE屬性的好處是可以根據表的結構直接定義結構類型變數,而不需要事先知道這個表的結構,而且當表的結構發生改變時, PL/SQL塊中的變數定義不需要修改。
記錄類型變數中包含若幹類型不同的數據,而集合類型變數中包含多個相同類型的元素。
要創建一個集合,先要定義一個集合類型,然後再定義該類型的集合變數。
定義集合類型的格式如下:
TYPE 類型名 IS TABLE OF 類型;
其中類型名是要創建的集合類型的名字,類型是指集合中每個元素的類型,每個元素的類型都相同。
元素類型可以是基本的數據類型,也可以是使用%TYPE屬性取得的另一個變數的類型,更複雜的情況是表中的一行,即集合中的每個元素是表中的一行數據。
例如,下麵的語句定義了一個集合類型,元素類型是整數。
TYPE IntSet IS TABLE OF integer;
在定義集合類型變數時,需要調用集合的構造函數,對集合變數進行初始化,為集合指定初始的元素,或者將其初始化為一個空集合。
例如:
intSetl IntSet := IntSet(l0,20,30);
intSet2 IntSet := IntSet();
註:集合的構造函數即為與類型名相同的函數。
在上述代碼中定義了兩個集合變數intSet1 和intSet2 ,並分別調用構造函數進行初始化,intSet1中包含三個元素, intSet2是一個空集合,不包含任何元素。
集合類型類似於面向對象技術中的類,除了提供構造函數外,還提供了一些方法,可以用來對集合進行操作。
下麵列出了集合的部分方法:
EXTEND(m, n) 將集合的第n個元素追加到集合末尾共m次。若不指定n ,則追加m個空元素。若不指定m 和n,則追加一個空元素。
COUNT 返回集合中當前包含的元素的個數。
FIRST 返回第一個元素的下標。
LAST 返回最後一個元素的下標
NEXT(n) 返回第N個元素之後的元素的下標
PRIOR(n) 返回第N個元素之前的元素的下標
EXISTS(n) 判斷第N個元素是否存在,若存在,則返回真值,否則返回假值。
通過這種方法定義的集合類型變數中的元素個數是確定的,通過EXTEND方法可以對變數中的元素進行擴展。
在使用集合變數時,一般是單獨使用其中的每個元素,可以對某個元素賦值,也可以輸出某個元素的值。
集合元素可以通過集合變數名和下標來引用,引用的方法為:
集合變數(下標)
下麵的例子演示了集合的使用方法:
DECLARE
TYPE IntSet IS TABLE OF integer;
intSet1 IntSet := IntSet( 10,20,30);
intSet2 IntSet := IntSet();
BEGIN
dbms_output.put_line ('集合intSetl 中元素的個數為:'|| intSet1.count);
intSet1.extend(2,3);
dbms_output.put_line ('擴充後集合intSetl 中元素的個數為:' || intSet1.count);
for i in 1 .. intSet1.count loop
dbms_output.put_line ('第' || i || '個元素的值為:' || intSet1( i) ) ;
end loop;
intSet2.extend(3);
intSet2(1):=100;
intSet2(2):=200;
intSet2(3):=300;
dbms_output.put_line ('集合intSet2 中元素為:');
for i in 1 .. intSet2.count loop
dbms_output.put_line ('第' || i || '個元素的值為:' || intset2(i));
end loop;
END;
實際上,還有一種定義記錄類型的方法,定義的格式為:
TYPE 類型名 IS TABLE OF 類型 INDEX BY BINARY_INTEGER;
在定義集合類型之後,就可以定義集合類型變數了。
通過這種方法定義的集合類型變數不需要進行初始化,在PL/SQL塊的可執行部分可以任意地為第n個元素賦值,但是不能通過EXTEND方能對變數進行擴展。
元素的實際數量就是被賦值的元素的個數。
下麵的代碼是使用這種定義方法的例子:
DECLARE
TYPE xyz IS TABLE OF integer INDEX BY BINARY_INTEGER;
intSet3 xyz;
BEGIN
intSet3(1):=100;
intSet3(2):=200;
intSet3(10):=1000;
dbms_output.put_line ('集合intSet3 中元素的個數為: ' || intSet3.count);
END;