Oracle(六)PL/SQL編程你知道多少

 

目錄

概述:

什麼是PL/SQL?

PL/SQL塊的主要組成部分:

格式:

注意規範: 

 變量與數據類型

      聲明變量:

     變量定義舉例:

標量變量

複合類型的變量

條件語句

if...then(單分支)

if...then..else(雙分支)

if...then ...elsif(多分支)

case  (不使用選擇器)

case(使用選擇器)

循環語句

LOOP循環

WHILE循環

FOR循環

遊標的使用

隱式遊標

顯式遊標

遊標for循環

異常處理

預定義的異常

使用SQLCODE、SQLERRM函數進行異常處理

非預定義異常

用戶定義的異常


 

 

概述:

PL/SQL是過程化的結構查詢語言(Procedural Language/Structured Query Language),它可以彌補SQL語句的不足。

PL/SQL中可以通過IFLOOP語句控制程序的執行流程,並且可以定義變量,以便利用這些變量在語句之間傳遞數據信息。

PL/SQLOracle的專用語言,是對標準SQL語言的擴展SQL語句可以嵌套在PL/SQL程序代碼中,將SQL的數據處理能力和PL/SQL的過程處理能力結合在一起。

 

什麼是PL/SQL?

PL/SQL程序的基本結構稱爲塊,編寫PL/SQL程序實際就是編寫PL/SQL塊。
PL/SQL是一種塊結構的語言,它將一組語句放在一個塊中,一次性的發送給服務器,執行代碼。
PL/SQL程序塊分爲無名塊、命名塊兩種。
無名塊指未命名的程序塊,它沒有被存儲,每次執行後都不能被重用。
命名塊指過程、函數、觸發器和程序包等,可存儲。
 

PL/SQL塊的主要組成部分:

          聲明部分、執行部分、異常處理部分

格式:

[DECLARE
DECLAREATION_STATEMENTS]
BEGIN
EXCUTABLE_STATEMENTS
[EXCEPTION
EXCEPTION _STATEMENTS]
END;

       說明:

聲明部分DECLARE開始,是可選的
聲明部分可以聲明一些PL/SQL變量、常量、遊標和異常等。當PL/SQL塊結束後,聲明部分的所有內容均不復存在。
在某個PL/SQL塊中聲明的內容只能在該塊中使用,其他塊不能使用。
執行部分BEGIN開始,是必須的
執行部分用於實現應用模塊的功能,該部分包含了要執行的PL/SQL語句和SQL語句。
異常處理部分EXCEPTION開始,是可選的
異常處理部分用於處理執行部分可能出現的運行錯誤。
ENDPL/SQL塊的結束標誌。如果存在異常則以關鍵字EXCEPTION結束。
 

注意規範: 

PL/SQL塊中的每一條語句都必須以分號結束SQL語句可以是多行的,但分號表示該語句結束。
一行中可以有多條SQL語句,但是他們之間必須以分號分隔。
 
註釋方法:
單行註釋:      --註釋內容
多行註釋:/*註釋內容*/

標識符的命名規範

當定義變量時,建議用v_作爲前綴。如v_sal
當定義常量時,建議用c_作爲前綴。如c_rate
當定義遊標時,建議用_cursor作爲後綴。如emp_cursor;
當定義異常時,建議用e_作爲前綴。如e_error
 

 變量與數據類型

        基本數據類型:BooleanBinary_intergerPls_intergerNumberIntCharVarchar2DateLong

        詳細使用可自行查閱資料

      聲明變量:

                             variable_name  data_type [ [NOT NULL]:=default_value_expression];  --有初始值

                              variable_name data_type [ [NOT NULL] DEFAULT default_value_expression];--無初始值

                              NOT NULL表示變量不允許爲空

     變量定義舉例:

SET SERVEROUTPUT ON  --顯示結果
declare
v_name varchar2(8):=‘PJ’;       --變量聲明
V_nowtime date:=sysdate;
begin
dbms_output.put_line(v_name);      --顯示輸出
dbms_output.put_line(v_nowtime);
end;
/                                --執行程序塊

 

   

      注意:使用DBMS_OUTPUT包來顯示查詢結果或文本行時,需先執行SET SERVEROUTPUT ON語句。

標量變量

如果變量只能保存一個值,則該變量稱爲“標量變量”。如:charnumber……

%TYPE變量

在聲明變量時,除了可以使用Oracle規定的數據類型外,還可以使用%TYPE關鍵字定義變量類型。
%TYPE關鍵字的含義是聲明一個與指定列名稱相同的數據類型
例如,下面的語句聲明瞭一個與EMP表中ENAME列完全相同的數據類型:
var_name emp.ename%type;

      又如何從表中拿到數據放進變量中呢   格式:into 變量名

select ename into v_name
    from emp
    where empno=7369;

 

複合類型的變量

如果變量能保存多個值(如表中的一行記錄,可參照爲結構體變量。一張表,可參照爲結構體數組),則該變量稱爲“複合類型的變量” 。如:%rowtype。可以通過.來調用成員變量
 
 %rowtype類型   :  變量名 表名%rowtype;    將一張表的結構給複合類型
 

定義格式 :v_name recode_name;

                   select *  into v_name  from 表名  --將表裏面所有數據放入變量

 
 
 
 

            

 

          自定義記錄類型  (類似於結構體定義)

 

          聲明格式:  type record_name is record(

                               字段名1 類型;   

                               字段名2 類型;

                                 .....

                              );
例:emp表中工號爲7369的職工的姓名(ename)、工種(job)、工資(sal)輸出顯示。

 

條件語句

if...then(單分支)

if <expression1> then  --expression1判斷條件
pl/sql_statement;--符合if條件後要執行的pl/qsl語句
end if;                                   

if...then..else(雙分支)

if <expression1> then
pl/sql_statement1;
else
pl/sql_statement2;
end if;                                  

if...then ...elsif(多分支)

if < expression1> then
       pl/sql_statement1;
elsif < expression2> then   ---注意這裏是elsif,和我們平常的習慣可能不同
       pl/sql_statement2;
……
else
       pl/sql_statement3;
end if;                              

case  (不使用選擇器)

case
when expression 1 then pl/sql_statement1;  --判斷每個when子句的條件
when expression 2 then pl/sql_statement2;
....
when expression n then pl/sql_statementn;
[else expression n+1 then pl/sql_statement;]

end;

case(使用選擇器)

case <selector>
when <expression1> then pl/sql_statement1;  --獲取選擇器的值,和每個when子句進行比較判斷
when <expression 2> then pl/sql_statement2;
....
when <expression n> then pl/sql_statementn;
[else <expression n+1> then pl/sql_statement;]

end;

循環語句

PL/SQL中,常用的循環語句有3種類型,Loop,while,for

 

LOOP循環

LOOP循環也稱爲無條件的循環。在這種類型的循環中如果沒有指定EXIT語句,循環將一直運行,即出現死循環。死循環是應該儘量避免的。因此,在LOOP循環中必須指定EXIT語句,以便循環停止執行。
loop
statements;--循環體
exit when condition;--跳出判斷
end loop;

WHILE循環

while condition --適用於事先無法知道控制循環終止變量值的情況。
loop
statements;
end loop;

FOR循環

FOR循環則使用一個循環記數器,並通過它來控制循環執行的次數。該計數器可以從小到大進行記錄,也可以相反,從大到小進行記錄。如果不滿足循環條件,則終止循環。
for loop_variable_name in [reverse] lower_bound..upper_bound
-- loop_variable_name 是指定循環計數器,可以使用已經有的,也可以使用一個新的。
-- 省略reverse,就是升序,不省略就是逆序。
-- for循環會自己,自增或自減1.不能在循環體裏動態的去改變loop_variable_name的值
loop
statements;
end loop;

遊標的使用

SQL 提供遊標機制來實現在程序設計語言中處理集合

遊標的作用就相當於指針,通過遊標程序設計語言就可以一次處理查詢結果集中的一行。

在Oracle中,遊標可以分爲兩大類:靜態遊標和REF遊標。

靜態遊標又可以分爲顯式遊標和隱式遊標。隱式遊標和顯示遊標都是靜態定義。在編譯的時候結果集就已經被確定。
REF遊標是一種引用類型,類似於指針。如果想在運行的時候動態確定結果集,就要使用REF遊標.
 
 

隱式遊標

在執行一個SQL語句時,Oracle會自動創建一個隱式遊標。這個遊標是內存中處理該語句的工作區域,在其中存儲了執行SQL語句的結果。通過遊標的屬性可獲知SQL語句的執行結果,以及遊標的狀態信息

遊標的主要屬性:

%FOUND       --若影響至少一條語句,返回true
%NOTFOUND   --與found相反
%ISOPEN          --遊標是否打開(用於顯式遊標)
%ROWCOUNT   --返回受影響記錄條數。
 

當使用隱式遊標時,需要在前面加SQL(默認的遊標名)

       

 

         cursor for loop語句:SQL語句返回的結果集進行處理

for 遊標變量 in select語句
loop
DML操作
end loop;
 

顯式遊標

PL/SQL程序中處理結果集時,用戶也可以通過顯式定義遊標,然後手動操作該遊標處理結果集。
四個步驟:定義遊標,打開遊標,提取遊標數據,關閉遊標
 
--定義遊標:
  Cursor 遊標名 is select語句;  --不帶參數的遊標
  Cursor 遊標名(參數名1 類型名1,參數名2 類型名2,……) is select語句; --帶參數的遊標
--打開遊標
  open 遊標名;
  open 遊標名(實參值1,實參值2,……)
--提取遊標數據
   fetch 遊標名 into 記錄變量名;
--關閉遊標。
   close 遊標名;

舉例:

遊標for循環

 

遊標通常是與循環聯合使用。實際上,PL/SQL還提供了一種將兩者綜合在一起的語句,即遊標FOR循環語句。遊標FOR循環是顯式遊標的一種快捷使用方式,它使用FOR循環依次讀取結果集中的數據。FOR循環開始時,遊標會自動打開(不需要使用OPEN方法),每循環一次系統自動讀取遊標當前行的數據(不需要使用FETCH),當退出FOR循環時,遊標被自動關閉(不需要使用CLOSE

 

 
--在SCOTT模式下顯示工資排名前5的員工的編號、姓名和工資。

declare
cursor emp_cur is select empno,ename,sal from
		(select empno,ename,sal from emp order by sal desc) where rownum<6;
begin
for i in emp_cur loop
dbms_output.put_line(i.empno|| ' ' || i.ename|| ' '|| i.sal);
end loop;
end;
/

 

 

異常處理

在編寫PL/SQL程序時,不可避免地會出現一些錯誤。在Oracle系統中使用異常來處理這些錯誤,這些異常都可以包括在PL/SQL程序的EXCEPTION塊中。Oracle系統提供了許多內置的異常,用戶也可以根據自己的需要定義異常

Oracle系統中的異常可以分爲3

預定義的異常:Oracle提供,用戶無需在程序中定義,由Oracle自動引發。

非預定義異常:數據庫本身不知道、不能控制的錯誤。需要用戶在程序中定義,然後由Oracle自動引發。

用戶定義的異常:違反了業務邏輯,程序員可以明確定義並引發。

 

預定義的異常

舉例:

使用SQLCODESQLERRM函數進行異常處理

非預定義異常

在一個異常產生、被捕獲並處理之前,它必須被定義。Oracle定義了幾千個異常,絕大多數只有錯誤編號和相關描述,僅僅命名了21個最常被用到的異常,即系統預定義異常。這些異常的名稱被儲存在STANDARDUTL_FILEDBMS_SQL這幾個系統包中。

使用pragma exception_init語句可以爲錯誤關聯一個名字

--已知Oracle中一錯誤代碼ORA-01400: 無法將 NULL 插入,
--請將該錯誤代碼與NULL_INSERT_ERROR進行關聯,並利用Scott模式下的表(
--例如,emp或dept)操作,舉例報出該錯誤。
declare
null_insert_error exception;
pragma exception_init(null_insert_error,-1400);

begin

insert into emp(empno) values(NULL);

exception
when null_insert_error then
dbms_output.put_line('無法將NULL插入');
end; 

用戶定義的異常

程序開發人員可以根據具體的業務邏輯規則,自定義一個異常。這樣,當用戶操作違反了業備邏輯規則後,就引發一個自定義異常,從而中斷程序的正常執行,並轉到自定義的異常處理部分。

--定義異常處理
declare
異常名 exception;

--觸發異常處理
raise 異常名;

--處理異常,在exception,中處理
--自定義一個異常,在SCOTT模式下,如果查找到EMP表中的某一員工
--(員工編號由用戶任意輸入)的佣金(COMM字段)爲0時,則顯示自定義錯誤消息“該員工的佣金爲0”。


declare
v_sal emp.sal%type;
e_sal exception;
v_eno emp.empno%type:=&no;
		
begin
select sal into v_sal from emp where empno=v_eno;
if emp_cur.sal=0 then --觸發異常的邏輯判斷
raise e_sal;

exception 
when e_sal then 
dbms_output.put_line('該員工的佣金爲0!');

end;
/

 

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