1.PL/SQL的定義:
PL/SQL(Procedure Language/SQL)
PLSQL是Oracle對sql語言的過程化擴展
指在SQL命令語言中增加了過程處理語句(如分支、循環等),使SQL語言具有過程處理能力。
把SQL語言的數據操縱能力與過程語言的數據處理能力結合起來,使得PLSQL面向過程但比過程語言簡單、高效、靈活和實用。
Plsql(oracle),Transact-sql(SQL server)
2.入門程序-->打印hello world;set serveroutput on;
--聲明變量 如果沒有可以不寫
declare
-- 開始
begin
dbms_output.put_line('hello world!');
--結束 必須加上分號
end;
/
運行結果:
注意:如果要在屏幕上輸出信息,需要將serveroutput開關打開:
3.聲明變量
1)方式一:
set serveroutput on;
declare
--聲明一般的變量,可以指定初始值,注意要使用:=
vname emp.ename%type;--和數據庫中的變量的類型保持一致
vsal number :=0;--聲明爲number類型
begin
--把查詢的結果賦值給變量
select ename,sal into vname,vsal from emp where empno=7839;
--顯示結果
dbms_output.put_line(vname||'的薪水是'||vsal);
end;
/
運行結果:
2)方式二
set serveroutput on;
accept empno prompt '請輸入員工編號';
declare
--聲明記錄變量
rec_emp emp%rowtype;
begin
--把查詢出來的結果賦值給變量
select * into rec_emp from emp where empno=&empno;
dbms_output.put_line(rec_emp.ename||'的薪水是'|| rec_emp.sal);
end;
/
運行結果:
4.if
set serveroutput on;
accept num prompt '請輸入數字';
declare
--定義變量
vnum number;
vstr varchar2(5);
begin
vnum:= #
if vnum>0 then vstr:='正數';
elsif vnum<0 then vstr:='負數';
else vstr:='零';
end if;
dbms_output.put_line(vstr);
end;
/
5.循環
1)循環方式一
set serveroutput on
begin
for i in 1..10
loop
--循環體內容
dbms_output.put_line(i);
end loop;
end;
/
2)循環方式二(這種方式比較常用)
set serveroutput on;
declare
vnum number :=1;--初始化變量
begin
loop
--退出循環的條件
exit when vnum>10;
dbms_output.put_line(vnum);
--加一
vnum:=vnum+1;
end loop;--結束循環
end;
/
3)循環方式三:
set serveroutput on;
declare
vnum number :=1;
begin
--當條件成立,就執行循環體
while vnum<10
loop
dbms_output.put_line(vnum);
--加一
vnum:=vnum+1;
end loop;
end;
/
運行結果:
6.光標
set serveroutput on;
/*要求:顯示總員工數和所有員工的姓名和工資
* select ename,sal from emp;
*/
declare
--聲明光標
cursor c_emp is select ename,sal from emp;
--定義變量
vcount number;
vname emp.ename%type;
vsal number;
begin
--查詢並顯示員工總數量
select count(*) into vcount from emp;
dbms_output.put_line('總的員工數爲:'||vcount);
--要使用光標就需要打開光標
open c_emp;
--循環
loop
--先取出一行記錄
fetch c_emp into vname,vsal;
--指定退出循環的條件
exit when c_emp%notfound;
dbms_output.put_line(vname||'的工資是'||vsal);
end loop;
--關閉光標
close c_emp;
end;
/
運行結果:
注:這裏查詢的結果和與cmd命令行查詢的結果一致
7.光標應用案例:給員工漲工資
set serveroutput on
--要求 :按照員工的工種漲工資,總裁(PRESIDENT) 1000 ,經理(MANAGER)800 其他員工 400
--分析:取出所有員工,每一個員工就行判斷,符合什麼條件,就漲多少工資
--select empno,empjob from emp;
-- update emp set sal=sal+? where empno=?
declare
--定義一個光標(所有員工的集合)
cursor c_emp is select empno,empjob from emp;
--定義與光標有關的變量
vempno emp.empno%type;
vempjob emp.empjob%type;
begin
open c_emp;
loop
--獲取數據
fetch c_emp into vempno,vempjob;
exit when c_emp%notfound;--指定退出循環的條件
--判斷是什麼情況 就漲多少工資
if vempjob='PRESIDENT' then update emp set sal=sal+1000 where empno=vempno;
elsif vempjob='MANAGER' then update emp set sal=sal+800 where empno=vempno;
else update emp set sal=sal+400 where empno=vempno;
end if;--結束if判斷
end loop;
close c_emp;
commit; --提交事務
dbms_output.put_line('執行完畢');
end;
/
運行結果:
8.帶參數的光標
set serveroutput on;
--要求:顯示10號部門中的總員工數,和每個員工的姓名和工資信息
declare
--定義光標
cursor c_emp(dno number) is select ename,sal from emp where deptno=dno;
--定義與光標相關的變量
vename emp.ename%type;
vsal emp.sal%type;
vdeptno emp.deptno%type;
vcount number;
begin
--獲取查詢條件
vdeptno :=&input_deptno;
--顯示 部門中的總員工數
select count(*) into vcount from emp where deptno=vdeptno;
dbms_output.put_line('總的員工數爲:'||vcount);
--打開光標
open c_emp(vdeptno);
loop
fetch c_emp into vename,vsal;
exit when c_emp%notfound;
dbms_output.put_line(vename||'的工資是'||vsal);
end loop;
close c_emp;--關閉光標
end;
/
運行結果:
9.異常
set serveroutput on
declare
vnum number;
begin
vnum:=1/0;
--處理異常
exception
when zero_divide then dbms_output.put_line('異常:被0除');
end;
/
運行結果:
10.自定義異常
set serveroutput on;
--自定義異常
declare
--聲明一個異常類型
my_exception exception;
begin
--拋出異常
raise my_exception;
exception
--異常處理
when my_exception then dbms_output.put_line('自定義異常');
end;
/
運行結果: