1. 程式人生 > 其它 >Oracle的pl/sql程式設計

Oracle的pl/sql程式設計

Pl/sql是在標準sql語句基礎上擴充套件的一種對oracle資料庫進行程式設計的語句

 

編寫規範

單行註釋–

多行註釋/* */

1. 當定義變數時,建議用v_作為字首v_sal

2. 當定義常量時,建議用c_作為字首c_rate

3. 當定義遊標時,建議用_cursor作為字尾emp_cursor

4. 當定義例外時,建議用e_作為字首e_error

儲存過程,函式,觸發器,包。他們的基本程式設計單元是塊。

塊的結構:

Declare 定義部分---定義常量,變數,遊標,例外,複雜資料型別

Begin 執行部分---要執行的pl/sql語句和sql語句

Exception 例外處理部分---處理執行的各種錯誤

End;

注:Declare和exception部分是可選,並不是必須的。

 

儲存過程 Procedure

建立過程語法:

Createprocedure 過程名(引數1...)

Is

Begin

執行語句;

End;

/

注:可不帶引數,若帶參格式為---(引數名 型別)--(in_empno number)

 

建立好過程,需要呼叫:

Exec過程名(引數1…);

 

 

 

 

Dbms_output是oracle所提供的包,該包包含一些過程,put_line就是dbms_output包的一個過程。

 

1. 只包含執行部分的案例:

輸出’hello’

Begin

Dbms_output.put_line(‘hello,world’);

End;

說明:在預設情況下,‘hello world’不輸出,需要setserveroutput on;

2.

案例:根據使用者輸入的僱員編號,顯示該僱員的名字

說明:&表示要接收從控制檯輸入的變數

|| 表示把兩個串拼接

 

Declare

--定義變數的格式是:變數名稱 變數的型別

v_enamevarchar2(8);

begin

--into 變數名 把查詢的ename值放入v_ename變數

selectename into v_ename form emp where empno=&empno;

--輸出v_ename

Dbms_output.put_line(‘僱員名是’||v_name);

End;

/

把上面的塊,改為procedure

Createprocedure pro1(in_empno number) is

v_enamevarchar2(8);

begin

selectename into v_ename from emp where empno=in_empno;

Dbms_output.put_line(‘僱員名是’||v_name);

End;

/

 

執行:exec pro1(7369);

 

 

包含定義部分,執行部分和例外處理部分的塊

1. 比如在例項2中,如果輸入了不存在的僱員好,應當做例外處理

如果我們輸入的使用者編號不存在,則系統會提示異常,為了更加明確的指出錯誤,oracle提供了exception處理機制

快速入門:

Declare

v_ename varchar2(36)

begin

select ename into v_ename from emp where empno=&empno;

dbms_output.put_line(‘僱員名’||v_ename);

exception

when no_data_found then

dbms_output.put_line(‘你輸入的編號有誤!’);

end;

 

對該案例的細節說明:

這裡涉及到底異常處理:

異常的基本語法:

 

Exception

When 異常的名稱 then

//對異常進行處理的程式碼

//對異常進行處理的程式碼

When異常的名稱2 then

//對這種異常處理

end;

 

注:then 後面都屬於處理,可以有新增刪除等等操作。

 

oracle提供的異常(參考pl/sql官方文件)

 

異常處理作用:

1. 可以給出捕獲異常,並給出明確提示。

2. 有時可以利用異常,來進行業務處理

 

Declare

v_ename varchar2(36)

begin

select ename into v_ename from emp whereempno=&empno;

dbms_output.put_line(‘僱員名’||v_ename);

exception

when no_data_found then

dbms_output.put_line(‘你輸入的編號有誤!我幫你加一條’);

insert into emp (empno,ename) values(1.’馬大哈’);

end;


過程的進一步講解:

Oracle過程,可以指定引數是輸入的引數,還是輸出的引數。

語法:create procedure 過程名(引數名 in 引數型別……引數名 out 引數型別……)is

//定義變數

Begin

//執行的語句

End;

注:變數可以有多個,預設是in

 

當編寫過程時,可以輸入show error 來顯示具體的錯誤

 

函式Function

函式和過程的區別:

函式必須有返回值(return),而過程可以沒有。

 

建立函式時,在函式頭部必須包含return子句,而在函式體內必須包含return語句返回的資料。可以使用create function 來建立函式。

語法:

Createfunction 函式名(引數1…)

Return返回的資料型別 is

--定義變數

Begin

--執行語句

Return變數名 //把變數返回

End;

注:觀察和過程的不同,在引數後面多一句return。

 

快速入門:

案例:請編寫一個函式,可以接收使用者名稱並返回該使用者的年薪。

Createor replace function fun1(in_v_ename varchar2)

Returnnumber is

--定義一個變數,來接收年薪

V_annual_salnumber;

Begin

Select(sal+nvl(comm,0))*13 into v_annual_sal from emp where ename=in_v_ename;

Returnv_annual_sal;

End;

/

 

呼叫函式
Select函式名(實際引數) from dual;

注:因為函式體裡已經定義了查詢哪個表,所以from後面寫dual虛表就可以了。

若寫emp,相當於查詢很多次,會返回很多次結果。

Selectfun1(‘SMITH’) from emp; //函式方法的使用就和MAX,MIN一樣了。

 

包Package

包用於在邏輯上組合過程和函式,它由包規範和包體兩部分組成。

包的規範只包含了過程和函式的說明,但是沒有過程和函式的實現程式碼。(像是java中的介面)

包體用於實現包規範中的過程和函式。

 

包規範
基本語法:

Createpackage 包名 is

--宣告過程

Procedure過程名(引數名 引數型別...);

--宣告函式

Function函式名(引數名 引數型別..) return 資料型別;

End;

 

注:可以把包規範想象為定義介面,而包體是實現介面

包的快速入門:

案例:編寫一個包,該包有一個過程,該過程可以接收使用者名稱和新的薪水,(將來用於通過使用者名稱去更新薪水)還有一個函式,該函式可以接收一個使用者名稱,(將來要實現得到使用者的年薪是多少)。

Createor replace package mypackage1 is

--宣告第一個過程

Procedurepro1(v_in_ename varchar2,v_in_newsal number);

--宣告一個函式

Functionfun1(v_in_ename varchar2) return number;

End;

 

包體 create packagebody
Create or replace package body 包名 is

--實現過程

Procedure 過程名(引數列表…) is

--定義變數

Begin

--執行語句

End;

 

--實現過程

Create function 函式名(引數列表…) return 資料型別 is

--定義變數

Begin

--執行

End;

End;

 

注:每個end是各自匹配的。

 

快速入門:

把前面包中的宣告的函式和過程實現。

Create ot replace package body mypackeageis

--實現過程

Procedure pro1(v_in_enamevarchar2,v_in_newsal number) is

Begin

Update emp set sal=v_in_newsal whereename=v_in_ename;

End;

--實現函式

Function fun1(v_in_ename varchar2) returnnumber is

V_annual_sal number;

Begin

Select (sal+nvl(comm,0))*13 intov_annual_sal from emp where ename=v_in_ename;

Return v_annual_sal;

End;

End;

 

注:包體中要實現的方法或者過程,應當先在包中宣告才可以

呼叫包的過程或函式:

exec 方案名.包名.過程名或函式名(引數…)

當呼叫包的過程或者函式時,在過程和函式前需要帶包名,如果要訪問其它方案的包,需要在包名前加方案名。

例: Exec scott.mypackage.pro1(引數…);或exec scott.mypackage.fun1(引數…);

 

 

觸發器

觸發器是一個隱含執行的過程。它不是由程式設計師或者dba來顯示呼叫,而是因為某個操作引發執行的。
————————————————
版權宣告:本文為CSDN博主「JasonZii」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/JasonZi/article/details/78401718