1. 程式人生 > >Oracle儲存過程及函式的練習題

Oracle儲存過程及函式的練習題

--儲存過程、函式練習題

--(1)建立一個儲存過程,以員工號為引數,輸出該員工的工資
create or replace procedure p_sxt1(v_empno in emp.empno%type, v_sal out emp.sal%type) is
begin
select sal into v_sal from emp where empno = v_empno;
end;
--(1)執行
declare
v_empno emp.empno%type := 7369;
v_sal emp.sal%type;
begin
p_sxt1(v_empno,v_sal);
dbms_output.put_line(v_empno || ' 員工的工資為:' || v_sal);
end;


--(2)建立一個儲存過程,以員工號為引數,修改該員工的工資。若該員工屬於10號部門,
--則工資增加150;若屬於20號部門,則工資增加200;若屬於30號部門,則工資增加250;
--若屬於其他部門,則增加300。
create or replace procedure p_sxt2(v_empno in emp.empno%type) is
v_deptno emp.deptno%type;
v_sal emp.sal%type;
begin
select deptno into v_deptno from emp where empno = v_empno;
select sal into v_sal from emp where empno = v_empno;
dbms_output.put_line(v_empno || ' 的部門是 ' || v_deptno || ' 修改前的工資是 ' || v_sal);

case v_deptno
when 10 then
update emp set sal = sal + 150 where empno = v_empno;
when 20 then
update emp set sal = sal + 200 where empno = v_empno;
when 30 then
update emp set sal = sal + 250 where empno = v_empno;
else
update emp set sal = sal + 300 where empno = v_empno;
end case;

select sal into v_sal from emp where empno = v_empno;
dbms_output.put_line(v_empno || ' 的部門是 ' || v_deptno || ' 修改後的工資是 ' || v_sal);
commit;
end;
--(2)執行
begin
p_sxt2(7369);
end;


--(3)建立一個儲存過程,以員工號為引數,返回該員工的工作年限(以引數形式返回)。
create or replace procedure p_sxt3(v_empno in emp.empno%type, v_year out number) is
begin
select round((sysdate - hiredate)/365,1) into v_year from emp where empno = v_empno;
end;
--(3)執行
declare
v_empno emp.empno%type := 7369;
v_year number;
begin
p_sxt3(v_empno,v_year);
dbms_output.put_line(v_empno || ' 工作年限為 ' || v_year || '年');
end;


--(4)建立一個儲存過程,以部門號為引數,輸出入職日期最早的10個員工資訊。
create or replace procedure p_sxt4(v_deptno emp.deptno%type) is
cursor c_emp is select * from emp where deptno = v_deptno order by hiredate;
v_times number := 0;
begin
for v_emp in c_emp loop
v_times := v_times + 1;
dbms_output.put_line(v_emp.empno || '**' || v_emp.ename || '**' || to_char(v_emp.hiredate,'yyyy-mm-dd'));
if v_times = 10 then
exit;
end if;
end loop;
end;
--(4)執行
begin
p_sxt4(20);
end;


--(5)建立一個函式,以員工號為引數,返回該員工的工資。
create or replace function f_sxt5(v_empno emp.empno%type) return emp.sal%type is
vr_sal emp.sal%type;
begin
select sal into vr_sal from emp where empno = v_empno;
return vr_sal;
end;
--(5)執行
select f_sxt5(7369)||'元' 工資 from dual;


--(6)建立一個函式,以部門號為引數,返回該部門的平均工資。
create or replace function f_sxt6(v_deptno emp.deptno%type) return emp.sal%type is
vr_sal emp.sal%type;
begin
select avg(sal) into vr_sal from emp where deptno = v_deptno;
return vr_sal;
end;
--(6)執行
select f_sxt6(20) 部門平均工資 from dual;


--(7)建立一個函式,以員工號為引數,返回該員工所在的部門的平均工資。
create or replace function f_sxt7(v_empno emp.empno%type) return emp.sal%type is
vr_sal emp.sal%type;
begin
select avg(sal) into vr_sal from emp where deptno = (select deptno from emp where empno = v_empno);
return vr_sal;
end;
--(7)執行
select f_sxt7(7369) from dual;


--(8)建立一個儲存過程,以員工號和部門號作為引數,修改員工所在的部門為所輸入的部門號。
--如果修改成功,則顯示“員工由……號部門調入調入……號部門”;如果不存在該員工,則顯示
--“員工號不存在,請輸入正確的員工號。”;如果不存在該部門,則顯示
--“該部門不存在,請輸入正確的部門號。”。
create or replace procedure p_sxt14(v_empno in emp.empno%type, v_deptno in emp.deptno%type) is
vt_empno number := 0;
vt_deptno number := 0;
vm_deptno emp.deptno%type;
begin
select count(*) into vt_empno from emp where empno = v_empno;
select deptno into vm_deptno from emp where empno = v_empno;
select count(distinct deptno) into vt_deptno from emp where deptno = v_deptno;

if vt_empno = 0 then
dbms_output.put_line('員工號不存在,請輸入正確的員工號。');
end if;
if vt_deptno = 0 then
dbms_output.put_line('該部門不存在,請輸入正確的部門號。');
end if;

if vt_empno = 1 and vt_deptno = 1 then
dbms_output.put_line('員工由 ' || vm_deptno || ' 號部門調入調入 ' || v_deptno || ' 號部門');
update emp set deptno = v_deptno where empno = v_empno;
commit;
end if;
end;
--(8)執行
begin
p_sxt14(7369,30);
end;


--(9)建立一個儲存過程,以一個整數為引數,輸入工資最高的前幾個(引數值)員工的資訊。
create or replace procedure p_sxt15(v_number in number) is
cursor c_emp is select * from emp order by sal desc;
v_n number := 0;
begin
for v_emp in c_emp loop
v_n := v_n + 1;
dbms_output.put_line(v_n || ' - ' || v_emp.ename || ' - ' || v_emp.sal);
if v_n = v_number then
exit;
end if;
end loop;
end;
--(9)執行
begin
p_sxt15(5);
end;


--(10)建立一個儲存過程,以兩個整數為引數,輸出工資排序在兩個引數之間的員工資訊。
create or replace procedure p_sxt16(v_up in number,v_down in number) is
cursor c_emp is select * from emp order by sal desc;
v_n number := 0;
begin
for v_emp in c_emp loop
v_n := v_n + 1;
if v_n >= v_up and v_n <= v_down then
dbms_output.put_line(v_n || ' - ' || v_emp.ename || ' - ' || v_emp.sal);
end if;
end loop;
end;
--(10)執行
begin
p_sxt16(2,3);
end;