1. 程式人生 > >Oracle學習筆記之PL/SQL編程

Oracle學習筆記之PL/SQL編程

.cn 數據操作 dmi int 直接 字節 sql編程 gin number

SQL(Structure Query Language)的含義是結構化查詢語句,最早由Boyce和Chambedin在1974年提出,稱為SEQUEL語言。1976年,IBM公司的San Jose研究所在研制關系數據庫管理系統System R時修改為SEQUEL2,即目前的SQL語言。1976年,SQL開始在商品化關系數據庫管理系統中應用。1982年美國國家標準化組織ANSI確認SQL為數據庫系統的工業標準。目前,許多關系型數據庫供應商都在自己的數據庫中支持SQL語言,如:Access、Sybase、SQL Server、Infomix、DB2等。

PL/SQL也是一種程序語言,叫做過程化SQL語言(Procedural Language/SQL)。PL/SQL是Oracle數據庫對SQL語句的擴展。在普通SQL語句的使用上增加了編程語言的特點,所以PL/SQL就是把數據操作和查詢語句組織在PL/SQL代碼的過程性單元中,通過邏輯判斷、循環等操作實現復雜的功能或者計算的程序語言。

PL/SQL編制的程序代碼如下所示

DECLARE

xm varchar2(8):=’麗麗’;

zym varchar2(10):=’計算機’;

zxf number(2):=45;

A integer:=1;

BEGIN

UPDATE XS

SET zxf=zx

WHERE xm=xm; /*更新學生表*/

IF SQL%NOTFOUND THEN

/*檢查記錄是否存在,如果不存在就插入記錄*/

INSERT INTO XS(XH,XM,ZYM,ZXF)

VALUES(1,xm,zym,zxf);

END IF;

END;

合法字符:

在使用PL/SQL進行程序設計時,可以使用的有效字符包

括以下3類:

(1)所有的大寫和小寫英文字母;

(2)數字0~9;

(3)符號() + - * / <> = ! ~ ;:. ` @ % , " # ^ & _ { } ? [ ]。

PL/SQL標識符的最大長度為30個字符,不區分大小寫,但是適當地使用大小寫可以提高程序的可讀性。

技術分享

PL/SQL中變量聲明格式:

(1) 變量必須以字母(A~Z)開頭

(2) 其後跟可選的一個或多個字母、數字(0~9)或特殊字符$、# 或_

(3) 變量長度不超過30個字符

(4) 變量名中不能有空格

技術分享

常用數據類型:

(1)VARCHAR類型:

語法格式:

var_field VARCHAR(n);

其中長度值n是本變量的最大長度且必須是正整數,例如:

var_field VARCHAR(11);

在定義變量時,可以同時對其進行初始化,例如:

var_field VARCHAR(11):=’Hello world’;

(2)NUMBER類型:

NUMBER數據類型可用來表示所有的數值類型。

語法格式:

num_field NUMBER(precision,scale);

其中precision表示總的位數;scale表示小數的位數,scale缺省表示小

數位為0。如果實際數據超出設定精度則出現錯誤。例如:

num_field NUMBER(10,2);

num_field是一個整數部分最多使8位,小數部分最多是2的變量。

declare

v_no number:=10;

begin

v_no:=v_no/0;

dbms_output.put_line(v_no);

exception

when others then

dbms_output.put_line(‘分母不能為0‘);

end;

(3)DATE類型:

用來存放日期時間類型數據,用7個字節分別描述年、月、日、時、

分、秒。

語法格式:

date_field DATE;

日期缺省格式為DD-MON-YY,分別對應日、月、年,例如17-JUN-

2002。註意,月份的表達要用英文單詞的縮寫格式。日期的格式可

以設置為中文格式,例如17-六月-2002。

(4)BOOLEAN類型:

邏輯型(布爾型)變量的值只有true(真)或false(假)。邏輯型變量一般用

於判斷狀態,然後根據其值是“真”或是“假”來決定程序執行分支。關

系表達式的值就是一個邏輯值。

註意:boolean類型變量不能直接通過 dbms_output.put_line(參數);直接輸出,如果想輸出,必須通過if判斷;

條件判斷語句:

IF邏輯結構

IF邏輯結構有3種表達式。

(1) IF-THEN

語法格式:

IF Boolean_expression THEN /*條件表達式*/

Run_expression /*條件表達式為真時執行*/

END IF

(2) IF-THEN-ELSE

語法格式:

IF Boolean_expression THEN /*條件表達式*/

Run_expression /*條件表達式為真時執行*/

ELSE

Run_expression /*條件表達式為假時執行*/

END IF;

(3) IF-THEN-ELSIF-THEN-ELSE

語法格式:

IF Boolean_expression1 THEN

Run_expression1

ELSIF Boolean_expression2 THEN

Run_expression2

ELSE

Run_expression3

END IF;

declare

i number:=10;

begin

if i<=0

then

dbms_output.put_line(‘分母不能為0‘);

else

dbms_output.put_line(‘分母不能為2‘);

end if;

end;

declare

v_no number:=1000;

begin

if v_no>1000 then

dbms_output.put_line(‘1‘);

elsif v_no=1000 then

dbms_output.put_line(‘2‘);

else

dbms_output.put_line(‘3‘);

end if;

end;

循環操作語句:

(1) LOOP-EXIT-END循環

語法格式:

LOOP

Run_expression /*執行循環體*/

IF Boolean_expression THEN /*測試Boolean_expression是否符合退出條件*/

EXIT; /*滿足退出條件,退出循環*/

END IF;

END LOOP;

declare

i number;

begin

for i in 1..10

loop

dbms_output.put_line(i);

end loop;

end;

declare

i number;

sum1 number:=0;

begin

for i in 1..10

loop

sum1:=sum1 +i;

end loop;

dbms_output.put_line(sum1);

end;

--例:求10的階乘。

DECLARE

n NUMBER:=1;

count1 NUMBER:=2;

BEGIN

LOOP

n:=n*count1;

count1:=count1+1;

IF count1>10THEN

EXIT;

ENDIF;

ENDLOOP;

dbms_output.put_line(to_char(n));

END;

(2)LOOP-EXIT-WHEN-END循環

除退出條件檢測有所區別外,此結構與前一個循環結構

類似。

語法格式:

LOOP

Run_expression /*執行循環體*/

EXIT WHEN Boolean_expression /*測試是否符合退出條件*/

END LOOP;

--例:求10的階乘。

DECLARE

n NUMBER:=1;

count1 NUMBER:=2;

BEGIN

LOOP

n:=n*count1;

count1:=count1+1;

EXITWHEN count1=11;

ENDLOOP;

dbms_output.put_line(to_char(n));

END;

(3)WHILE-LOOP-END循環

語法格式:

WHILE Boolean_expression /*測試Boolean_expression是否符合退出條件*/

LOOP

Run_expression /*執行循環體*/

END LOOP;

--例:用WHILE-LOOP-END循環結構求10的階層。

DECLARE

n NUMBER:=1;

count1 NUMBER:=2;

BEGIN

WHILE count1<=10

LOOP

n:=n*count1;

count1:=count1+1;

ENDLOOP;

dbms_output.put_line(to_char(n));

END;

(4) FOR-IN-LOOP-END循環

語法格式:

FOR count IN count_1..count_n /*定義跟蹤循環的變量*/

LOOP

Run_expression /*執行循環體*/

END LOOP;

--例:用FOR-IN-LOOP-END循環結構求10的階層。

DECLARE

n NUMBER:=1;

count1 NUMBER;

BEGIN

FOR count1 IN2..10

LOOP

n:=n*count1;

ENDLOOP;

dbms_output.put_line(to_char(n));

END;

邏輯判斷語句:

1. CASE語句

CASE語句是在Oracle9i才引入的。

語法格式:

CASE input_name

WHEN expression1 THEN result_expression1

WHEN expression2 THEN result_expression2

WHEN expressionN THEN result_expression

[ELSE result_expressionN]

END;

例如:

DECLARE

ename_1 varchar2(20);

empno_1 varchar2(16);

v_Result varchar2(20);

BEGIN

SELECT empno,ename

INTO empno_1,ename_1

FROM emp

WHERE empno=‘7369‘;

CASE length(ename_1)/*判斷v_kch的值,並給出結果 */

WHEN1THEN v_Result:=‘名字有1個字符‘;

WHEN2THEN v_Result:=‘名字有2個字符‘;

WHEN3THEN v_Result:=‘名字有3個字符‘;

WHEN4THEN v_Result:=‘名字有4個字符‘;

when5then v_result:=‘名字有5個字符‘;

ELSE

v_Result:=‘Nothing‘;

ENDCASE;

dbms_output.put_line(v_result||‘:‘||ename_1);

END;

(5)使用%TYPE

%TYPE屬性提供了變量和數據庫列的數據類型。

my_xh XS.XH%TYPE;即:變量名 表名.列名%TYPE; 表示該屬性為某個表中的某個列的類型一致;

使用%TYPE聲明具有以下兩個優點:

① 不必知道XH列的確切的數據類型;

② 如果改變了XH列的數據庫定義,my_xh的數據類型在運行時會自動進行修改。

例如:

-- Created on 2017/10/19 by ADMINISTRATOR

declare

employeeNO emp.empno%type;--聲明employeeNO 屬性類型為emp表的empno列類型一致;

employeeName emp.ename%type;

deptNO number(5);

deptName varchar2(20);

i char(1):=2;

begin

if i=1then--註意比較通過一個=號

select deptno,dName into deptNO,deptName from dept where deptno=20;

dbms_output.put_line(‘查詢部門20的編號以及部門名稱:‘||deptno||‘:‘||deptName);

else

select empno,ename into employeeNO ,employeeName from emp where empno=7369;

dbms_output.put_line(‘查詢7369員工編號以及姓名:‘||employeeNO||‘:‘||employeeName);

endif;

end;

(6) E emp%ROWTYPE

可以使用%ROWTYPE屬性聲明描述表的行數據的記錄;

例如:

-- Created on 2017/10/19 by ADMINISTRATOR

declare

employee emp%rowtype;--聲明employee 屬性類型為emp表行類型一致;

department dept%rowType;--聲明deptartment變量為dept行類型;

i number(5):=2;

begin

if i=1then--註意比較通過一個=號

select deptno,dName into department.deptno,department.dname from dept where deptno=20;--可以直接將某列賦值給該變量中的某個字段

dbms_output.put_line(‘查詢部門20的編號以及部門名稱:‘||department.deptno||‘:‘||department.dname);

else

select emp.*into employee from emp where empno=7369;--可以直接將正行賦值給該變量

dbms_output.put_line(‘查詢7369員工編號以及姓名:‘||employee.empno||‘:‘||employee.ename||‘:‘||employee.hiredate);

endif;

end;

(7)數組類型:數據是具有相同數據類型的一組成員的集合。在PL/SQL中,數組數據類型是VARRAY。 定義VARRY數據類型語法如:

TYPE varray_name IS VARRAY(size) OF element_type [NOT NULL

例如:

DECLARE

--定義一個最多保存5個VARCHAR(25)數據類型成員的VARRAY數據類型

TYPE reg_varray_type ISVARRAY(5)OFVARCHAR(25);

--聲明一個該VARRAY數據類型的變量

v_reg_varray REG_VARRAY_TYPE;

BEGIN

--用構造函數語法賦予初值

v_reg_varray := reg_varray_type (‘中國‘,‘美國‘,‘英國‘,‘日本‘,‘法國‘);

DBMS_OUTPUT.PUT_LINE(‘地區名稱:‘||v_reg_varray(1)||‘、‘

||v_reg_varray(2)||‘、‘

||v_reg_varray(3)||‘、‘

||v_reg_varray(4));

DBMS_OUTPUT.PUT_LINE(‘賦予初值NULL的第5個成員的值:‘||v_reg_varray(5));

--用構造函數語法賦予初值後就可以這樣對成員賦值

v_reg_varray(5):=‘法國‘;

DBMS_OUTPUT.PUT_LINE(‘第5個成員的值:‘||v_reg_varray(5));

END;

(8)record用戶定義的記錄,必須聲明自己的域。記錄包含唯一的命名域,具有不同的數據類型。

DECLARE

TYPE TimeRec IS RECORD(HH number(2),MM number(2));

TYPE MeetingTyp IS RECORD

(

Meeting_Date date,

Meeting_Time TimeRec,

Meeting_Addr varchar2(20),

Meeting_Purpose varchar2(50)

)

例如:

declare

--type聲明一種自定義類型, is record表示該類型中包含有哪些屬性

TYPE TimeRec ISRECORD(empno number(10),deptno number(5));

a timeRec;--a變量為我們聲明timeRec類型

begin

select empno,deptno into a from emp where empno=7369;--into 表示賦值,註意一條語句中只能使用一次 且返回結果不能多條記錄

dbms_output.put_line(a.empno);--表示輸出

end;

Oracle學習筆記之PL/SQL編程