一、什麼是PL/SQL?
1、PL/SQL的概念
PL/SQL(Procedural Language/SQL、過程語言/SQL)是結合了Oracle過程語言和結構化查詢語言(SQL)的一種擴充語言。具體地講,PL/SQL就是在普通SQL語句的基礎上增加了程式設計語言的特點,将資料操作和查詢語句組織在PL/SQL代碼的過程性單元中,通過邏輯判斷、循環等操作實作複雜的功能或者計算的程式語言。
2、PL/SQL體系結構
PL/SQL引擎用來編譯和執行PL/SQL塊或子程式,該引擎駐留在Oracle伺服器中。PL/SQL引擎執行過程語句,而将SQL語句發送給Oracle伺服器上的SQL語句執行器,由SQL語句執行器執行這些SQL語句。PL/SQL體系結構如下:
3、PL/SQL塊簡介
PL/SQL 是一種塊結構的語言,它将一組語句放在一個塊中。PL/SQL程式由3個塊組成:聲明部分、執行部分、異常處理部分。
PL/SQL塊的結構:
DECLARE
--聲明部分:在此聲明PL/SQL的變量、類型及遊标,以及局部的存儲過程和函數。
BEGIN
--執行部分:過程及SQL語句,是程式的主要部分,不可省略
[EXCEPTION]
--執行異常處理部分:錯誤處理,可選
END;
(1)PL/SQL塊分類
(2)PL/SQL編碼标準
(3)常量和變量(constant)的聲明
PL/SQL程式設計中的辨別符定義與SQL的辨別符定義的要求相同,要求和限制如下:
①辨別符名不能超過30個字元
②第一個字元必須為字母
③不分大小寫
④不能用減号(-)
⑤不能是SQL保留字
命名——建議的命名方法如下:
給變量和常量聲明指派:
方法一:通過select...into...給變量指派
DECLARE
v_name VARCHAR2(10);
BEGIN
SELECT stuName INTO v_name FROM Student WHERE stuNo=1001;
dbms_output.put_line(v_name);
END;
方法二:通過指派操作符 := 給變量指派
二、資料類型及其用法
1、标量資料類型
标量資料類型包含單個值,沒有内部元件。變量資料類型包括數字、字元、布爾值和日期時間值4類資料類型
2、LOB資料類型
Oracle提供了LOB(Large Object)類型,用于存儲大的資料對象的類型。Oracle目前主要支援BFILE、BLOB、CLOB及NCLOB。
3、屬性類型
屬性用于引用變量或資料庫列的資料類型,以及表示表中一行的記錄類型。PL/SQL支援一下兩種屬性類型:
①%type
②%rowtype
③複合類型。
4、注釋
就像其他的進階開發語言一樣,為了使PL/SQL程式具有良好的可讀性和可維護性,我們在寫程式的時候應該注意向程式中添加注釋。注釋有以下兩種形式:
(1)行注釋
-- 作用範圍是一行。
(2)塊注釋
注釋一行或多行。
三、控制語句
PL/SQL程式可通過控制結構來控制指令執行的流程。标準的SQL沒有流程控制的概念,PL/SQL提供了豐富的流程控制語句。包括:條件控制、循環控制、順序控制。
1、條件控制
用于根據條件執行一系列語句。條件控制包括IF語句和CASE語句。
IF語句用法:
CASE語句用法:
2、循環控制
用于重複執行一系列語句。循環控制包括LOOP和EXIT語句,使用EXIT語句可以立即退出循環,使用EXIT WHEN語句可以根據條件結束循環。
在FOR循環中,每循環一次,循環變量自動加1:使用關鍵字REVERSE,循環變量自動減1,跟在IN REVERSE後面的數字必須是從小到大的順序,而且必須是整數,不能是變量或表達式。可以使用EXIT退出循環。
3、順序控制
DECLARE
v_number NUMBER(2):=1;
BEGIN
LOOP
dbms_output.put_line('v_number的值現在為:'||v_number);
v_number:=v_number+1;
IF (v_number>10)THEN
GOTO LabelOffLoop;--跳轉到标簽為LabelOffLoop的行
ELSE
NULL;--為了使文法有意義,去掉null會報文法錯誤
END IF;
END LOOP;
<<LabelOffLoop>>--标簽
dbms_output.put_line('循環跳轉到此處結束!');
END;
四、錯誤處理
1、預定義錯誤
Oracle預定義的異常情況大約有24個。對于這種異常情況的處理,無需在程式中定義,由Oracle自動将其引發。參照下表:
DECLARE
v_number NUMBER(2):=1;
BEGIN
v_number:=1/0;
EXCEPTION
-- WHEN zero_divide THEN
-- dbms_output.put_line('0被作為除數了!');
WHEN OTHERS THEN
dbms_output.put_line('發生了異常!');
END;
/*
其中OTHERS確定不會漏過任何異常,如果沒有在前面的異常處理部分顯示擷取命名異常,它就可以擷取其餘的異常。
PL/SQL塊隻能有一個OTHERS異常處理程式。
*/
可以使用函數SQLCODE和SQLERRM來傳回錯誤代碼和錯誤文本資訊。
DECLARE
v_number NUMBER(2):=1;
BEGIN
v_number:=1/0;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('錯誤代碼:'||sqlcode);
dbms_output.put_line('錯誤文本:'||SQLERRM);
END;
2、非預定義錯誤
3、使用者自定義錯誤
DECLARE
v_number NUMBER(2):=1;
out_of_index EXCEPTION;--定義異常類型
BEGIN
LOOP
dbms_output.put_line('v_number的值現在為:'||v_number);
v_number:=v_number+1;
IF (v_number>10)THEN
RAISE out_of_index;--抛出異常情況
ELSE
NULL;
END IF;
END LOOP;
EXCEPTION
WHEN out_of_index THEN
dbms_output.put_line('你已經越界了!!!');
END;
raise_application_error(error_number,error_message)的文法:
error_number表示使用者為異常指定的編号。該編号必須是介于20000~20999之間的負整數。
error_message表示使用者為異常指定的消息文本。消息長度可長達2048位元組。錯誤消息是與error_number表示關聯的文本。
DECLARE
v_number NUMBER(2):=1;
BEGIN
LOOP
dbms_output.put_line('v_number的值現在為:'||v_number);
v_number:=v_number+1;
IF (v_number>10)THEN
raise_application_error(-20001,'你已經越界了!!!');
ELSE
NULL;
END IF;
END LOOP;
END;