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