----pl/sql編程語言
----pl/sql編程語言是對sql語言的擴展,使得sql語言具有過程化編程的特性
----比一般的過程化編程語言,更加靈活高效
----主要是用來編寫存儲過程和存儲函數等
----聲明方法
----賦值操作可以用:=也可以使用into查詢語句賦值
declare
i number(2) :=10;
s varchar2(10) := '韓美娟';
ena emp.ename%type;----引用型變量
emprow emp%rowtype;----記錄型變量
begin
dbms_output.put_line(i);--輸出語句
dbms_output.put_line(s);
select ename into ena from emp where empno = 7788;
dbms_output.put_line(ena);
select * into emprow from emp where empno = 7788;
dbms_output.put_line(emprow.ename || '的工作爲' ||emprow.job);
end;
----pl/sql中的if判斷
----輸入小於18的數字,輸出未成年
----輸出大於18小於40的數字,輸出中年
----輸入大於40的數字,輸出老年人
declare
i number(3) := ⅈ
begin
if i<18 then
dbms_output.put_line('未成年');
elsif i<40 then
dbms_output.put_line('中年');
else
dbms_output.put_line('老年');
end if;
end;
----pl/sql中的loop循環
----用三種方式輸出1到10的數字
----第一種:while循環
declare
i number(2) :=1;
begin
while i<11 loop
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
----第二種:exit循環
declare
i number(2) :=1;
begin
loop
exit when i>10;
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
----第三種:for循環
declare
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
----遊標:類似java中的集合,可以存放多個對象,對行記錄
----輸出emp表中所有員工的姓名
declare
cursor c1 is select * from emp;
emprow emp%rowtype;
begin
open c1;
loop
fetch c1 into emprow;
exit when c1%notfound;
dbms_output.put_line(emprow.ename);
end loop;
close c1;
end;
----給指定部門員工漲工資
declare
cursor c2(eno emp.deptno%type)
is select empno from emp where deptno = eno;
en emp.empno%type;
begin
open c2(10);
loop
fetch c2 into en;
exit when c2%notfound;
update emp set sal=sal+100 where empno=en;
commit;
end loop;
close c2;
end;
----查詢10號部門員工信息
select * from emp where deptno=10;
----存儲過程
----存儲過程:存儲過程就是提前編譯好的一段pl/sql語言,放置在數據庫端
----可以直接被調用,這一段pl/sql一般都是固定步驟的業務。
----給指定員工漲100塊錢工資
create or replace procedure p1(eno emp.empno%type)
is
begin
update emp set sal=sal+100 where empno=eno;
commit;
end;
select * from emp where empno=7788;
----測試p1
declare
begin
p1(7788);
end;
----存儲函數
----通過存儲函數實現計算指定員工的年薪
----存儲過程和存儲函數的參數都不能帶長度
----存儲函數的返回值類型不能帶長度
create or replace function f_yearsal(eno emp.empno%type) return number
is
s number(10);
begin
select sal*12+nvl(comm, 0) into s from emp where empno = eno;
return s;
end;
--測試f_yearsal
---存儲函數在調用的時候返回值需要接收
declare
s number(10);
begin
s:=f_yearsal(7788);
dbms_output.put_line(s);
end;
----out類型參數如何使用
----使用存儲過程來算年薪
create or replace procedure p_yearsal(eno emp.empno%type,yearsal out number)
is
s number(10);
c emp.comm%type;
begin
select sal*12,nvl(comm,0) into s,c from emp where empno=eno;
yearsal := s+c;
end;
--測試p_yearsal
declare
yearsal number(10);
begin
p_yearsal(7788,yearsal);
dbms_output.put_line(yearsal);
end;
----in和out類型參數的區別:
----凡是涉及到into查詢語句賦值或者:=賦值操作的參數都必須使用out來修飾,其餘都用in,默認是in
----存儲過程和存儲函數的區別
----語法區別:關鍵字不一樣,存儲過程procedure,存儲函數是function
----存儲函數比存儲過程多了兩個return
----本質區別:存儲函數有返回值,存儲過程沒有返回值
----如果存儲過程想實現有返回值的業務,必須使用out類型的參數
----即便是存儲過程使用了out類型的參數,其本質也不是真的有了返回值
----而是在存儲過程內部給out類型參數賦值,在執行完畢後我們直接拿到輸出類型參數的值
----我們可以使用存儲函數有返回值的特性,來自定義函數
----而存儲過程不能用來自定義函數
----查詢出員工姓名,員工所在部門名稱
----案例準備工作:把scott用戶下的dept表複製到當前用戶下
create table dept as select * from scott.dept;
----使用傳統方式來實現案例需求
select e.ename,d.dname
from emp e,dept d
where e.deptno=d.deptno;
----使用存儲函數來實現提供一個部門編號,輸出一個部門名稱
create or replace function fdna(dno dept.deptno%type) return dept.dname%type
is
dna dept.dname%type;
begin
select dname into dna from dept where deptno=dno;
return dna;
end;
----使用fdna存儲函數來實現案例需求,查詢出員工姓名,員工所在部門名稱
select e.ename,fdna(e.deptno)
from emp e;
----觸發器:制定一個規則,在我們做增刪改操作時,只要滿足該規則自動觸發,無需調用
----語句級觸發器:不包含有for each row的就是語句級觸發器
----行級觸發器:包含有for each row的就是行級觸發器
--------加for each row是爲了使用:old或者:new對象或者一行記錄.
----插入一條記錄,輸出一個新員工入職
----語句級觸發器
create or replace trigger t1
after
insert
on person
declare
begin
dbms_output.put_line('一個新員工入職');
end;
----觸發t1
insert into person values(2,'憨憨');
commit;
select * from person;
----行級別觸發器
----不能給員工降薪
raise_application_error(-20001~-20999之間,'不能給員工降薪');
create or replace trigger t2
before
update
on emp
for each row
declare
begin
if :old.sal>:new.sal then
--異常
raise_application_error(-20001,'不能給員工降薪');
end if;
end;
----觸發t2
update emp set sal=sal-1 where empno=7788;
commit;
----觸發器實現主鍵自增
----分析思路:在用戶做插入操作之前拿到即將插入的數據
------給該數據中的主鍵列賦值
create or replace trigger auid
before
insert
on person
for each row
declare
begin
select s_person.nextval into :new.pid from dual;
end;
---查詢person表數據
select * from person;
----使用auid實現主鍵自增
insert into person (pname) values ('哈哈哈');
commit;