第四章 存储过程函数的练习题答案

练习:

(3)创建一个存储过程,以员工号为参数,返回该员工的工作年限(以参数形式返回)。
create or replace procedure pro_emp_date
(p_eno number,p_ename out varchar2,
p_date out number)
is
begin —两个日期相减是天数,相加是月数
select ename,trunc(months_between(sysdate,hiredate)/12)
into p_ename, p_date from emp
where empno=p_eno;
end;
存储过程已创建,调用:
declare
v_eno emp.empno%type :=&empno;
v_name emp.ename%type;
v_date number;
begin
pro_emp_date(v_eno,v_name,v_date);
dbms_output.put_line
(‘员工号是’||v_eno||’,员工姓名是’||v_name||‘的工作年限是:’||v_date||‘年’);
end;

(4)创建一个存储过程,以部门号为参数,输出入职日期最早的3个员工信息。
create or replace procedure pro_emp_earlydate(p_dno emp.deptno%type)
is
–此题只能用游标,因为要取出三条信息:
cursor c_emp is select * from emp
where deptno = p_dno order by hiredate;
row number := 0;
begin
for i in c_emp loop
row := row + 1;
dbms_output.put_line
(‘工号是:’||i.empno||’,姓名是:’||i.ename||‘入职日期是:’|| to_char(i.hiredate,‘yyyy-mm-dd’));
if row > 3 then
exit;
end if;
end loop;
end;
存储过程已创建,调用:
begin
pro_emp_earlydate(10);
end;

(9)创建一个存储过程,以一个整数为参数,输入工资最高的前几个(参数值)员工的信息。
create or replace procedure pro_empsal(p_num int)
is
cursor c_emp is select * from emp order by sal desc;
rn number := 0;
begin
for i in c_emp loop
rn := rn + 1;
dbms_output.put_line(‘第’||rn||‘名的姓名是:’||i.ename||’,工资是:’||i.sal);
if rn = p_num then
exit;
end if;
end loop;
end;
存储过程已创建,调用:
begin
pro_empsal(3);
end;

(10)创建一个存储过程,以两个整数为参数,输出工资排序在两个参数之间的员工信息。
create or replace procedure pro_emp_sal(p_num1 int,p_num2 int)
is
cursor c_emp is select * from emp order by sal desc;
rn number := 0;
begin
for i in c_emp loop
rn := rn + 1;
dbms_output.put_line(‘第’||rn||‘名的姓名是:’||i.ename||’,工资是:’||i.sal);
if rn between p_num1 and p_num2 then
exit;
end if;
end loop;
end;
存储过程已创建,调用:
begin
pro_emp_sal(3,6);
end;

(5)创建一个函数,以员工号为参数,返回该员工的工资。
create or replace function emp_getsal(f_eno emp.empno%type)
return number --返回工资的数据类型
is
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno=f_eno;
– (select deptno from dept where deptno = f_eno);如果emp表没有deptno,就需要使用子查询
return v_sal; --返回工资
end;
函数已创建,调用:
select ename,emp_getsal(empno) from emp;

(6)创建一个函数,以部门号为参数,返回该部门的平均工资。
create or replace function dept_getsal(f_dno dept.deptno%type)
return number–返回工资的数据类型
is
v_sal emp.sal%type;
begin
select avg(sal) into v_sal from emp where deptno= f_dno;
– (select deptno from dept where deptno = f_dno);如果emp表没有deptno,就需要使用子查询
return v_sal;–返回工资
end;
函数已创建,调用:
select deptno,dept_getsal(deptno) from emp;

(7)创建一个函数,以员工号为参数,返回该员工所在的部门的平均工资。
create or replace function emp_getsal(f_eno emp.empno%type)
return number
is
v_sal emp.sal%type;
begin
select avg(sal) into v_sal from emp where deptno=f_eno;
– (select deptno from emp where empno = f_eno);如果emp表没有deptno,就需要使用子查询
return v_sal;
end;
函数已创建,调用:
select ename,empno,emp_getsal(empno) from emp;

(8)创建一个存储过程,以员工号和部门号作为参数,修改员工所在的部门为所输入的部门号。
如果修改成功,则显示“该员工由……号部门调入,调入到……号部门”;
如果不存在该员工,则显示“员工号不存在,请输入正确的员工号。”;
如果不存在该部门,则显示“该部门不存在,请输入正确的部门号。”。
------当前题中最难的题,可能写的不准确,会违反约束条件,后面题是 标准写法
create or replace procedure p_sxt
(p_empno in emp.empno%type, p_deptno in emp.deptno%type)
is
v_empno number := 0;
v_deptno number := 0;
m_deptno emp.deptno%type;
begin
select count(*) into v_empno from emp where empno = p_empno;
select deptno into m_deptno from emp where empno = p_empno;
select count(distinct deptno) into v_deptno from emp where deptno = p_deptno;

if v_empno = 0 then
dbms_output.put_line(‘员工号不存在,请输入正确的员工号。’);
end if;

if v_deptno = 0 then
dbms_output.put_line(‘该部门不存在,请输入正确的部门号。’);
end if;

if v_empno = 1 and v_deptno = 1 then
dbms_output.put_line
(‘该员工由’||m_deptno||‘号部门调入,调入到’||p_deptno||‘号部门’);
update emp set deptno = p_deptno where empno = p_empno;
commit;
end if;

end;
存储过程已创建,调用:
begin
p_sxt(7369,10);
end;

----李老师答案:
CREATE OR REPLACE PROCEDURE AA(V_EMPNO NUMBER ,V_DEPTNO NUMBER)
AS
EMP_NUM NUMBER(10);
DEPT_NUM NUMBER(10);
OLD_DEPTNO NUMBER(10);
BEGIN
SELECT COUNT() INTO EMP_NUM FROM EMP WHERE EMPNO = V_EMPNO;
IF EMP_NUM = 0 THEN
DBMS_OUTPUT.PUT_LINE(‘员工号不存在,请输入正确的员工号。’);
END IF ;
SELECT COUNT(
) INTO DEPT_NUM FROM DEPT WHERE DEPTNO = V_DEPTNO;
IF DEPT_NUM = 0 THEN
DBMS_OUTPUT.PUT_LINE(‘该部门不存在,请输入正确的部门号。’);
END IF ;
IF EMP_NUM > 0 AND DEPT_NUM > 0 THEN
SELECT DEPTNO INTO OLD_DEPTNO FROM EMP WHERE EMPNO = V_EMPNO;
UPDATE EMP SET DEPTNO = V_DEPTNO WHERE EMPNO = V_EMPNO ;
COMMIT;
DBMS_OUTPUT.PUT_LINE(‘员工’||V_EMPNO||‘由’||OLD_DEPTNO||‘部门调入到’||V_DEPTNO||‘部门。’);
END IF;
END ;


/*函数:
2、
创建一个函数, 传入一个字符串,判断这个字符串是否是数字,如果是返回本身,不是返回0
*/
create or replace function f_if_number(p_parm in VARCHAR2)
return number
is
v_parm number;
begin
/select to_number(p_parm) into v_parm from dual;/
v_parm := abs(to_number(p_parm));
if abs(to_number(p_parm))>=0 then
dbms_output.put_line(v_parm); --是数字返回本身
return v_parm;
end if;
exception
when others then return 0; --不是数字返回0
end;
–函数已创建,调用:
select f_if_number(‘abc’) from dual; /返回0/
select f_if_number(‘123’) from dual; /返回本身


===========标准答案:
/*3. (3)创建一个存储过程,以员工号为参数,
返回该员工的工作年限(以参数形式返回)。
*/
create or replace procedure
we1 (p_empno in number default 7369,
p_sum out varchar )
as
v_empno emp.empno%type;
begin
select empno,
round(months_between(sysdate,hiredate)/12,0)
||‘年’ as year into v_empno,p_sum
from emp where empno=p_empno;
dbms_output.put_line(v_empno||’__’||p_sum);
end;

declare
v_empno number:=&empno;
v_year varchar2(10);
begin
we1(v_empno,v_year);
dbms_output.put_line(v_empno||’__’||v_year);
end;

/*4.创建一个存储过程,以部门号为参数,
输出入职日期最早的3个员工信息。
/
create or replace procedure we1
(p_deptno in number)
is
cursor we is select * from
(select rownum w,e.
from
(select * from emp where deptno=p_deptno
order by hiredate asc) e)
where w<4;
begin
for sd in we loop
dbms_output.put_line(sd.ename||’__’||sd.empno);
end loop;
end;

call we1(30);

/*5. (5)创建一个函数,以员工号为参数,
返回该员工的工资。
*/
create or replace function
getsal(v_empno number)
return number
as
v_sal number;
begin
select sal into v_sal from emp where empno=v_empno;
return v_sal;
end;
/*6. (6)创建一个函数,以部门号为参数,返回该部门的平均工资。
/
create or replace function getsal(v_deptno number)
return number
as
v_sal number;
begin
select avg(sal) into v_sal from emp
where deptno=v_deptno group by deptno;
return v_sal;
end;
/
(7)创建一个函数,以员工号为参数,
返回该员工所在的部门的平均工资。
*/
7.create or replace function getsal(v_empno number)
return number
as
v_sal number;
v_deptno number;
begin
select deptno into v_deptno
from emp where empno=v_empno;
select avg(sal) into v_sal
from emp where deptno=v_deptno
group by deptno;
return v_sal;
end;
—子查询
select avg(sal) into v_sal
from emp where
deptno=(select deptno
from emp where empno=v_empno);

/*
8.创建一个存储过程,以员工号和部门号作为参数
,修改员工所在的部门为所输入的部门号。
如果修改成功,
则显示“员工由……号部门调入调入……号部门”;
如果不存在该员工,则显示
“员工号不存在,请输入正确的员工号。”;
如果不存在该部门,则显示
“该部门不存在,请输入正确的部门号。”。*/

create or replace procedure
we1 (p_empno in number,p_deptno in number)
is
v_deptno emp.deptno%type;
w emp.deptno%type;
e emp.deptno%type;
begin
–确定员工是否存在
select count() into w from emp
where empno=p_empno;
–确定部门是否存在
select count(
) into e from dept
where deptno=p_deptno;

  if  w=0  then
     dbms_output.put_line(p_empno||'员工号不存在,请输入正确的员工号。');
  end if;
  if  e=0 then
     dbms_output.put_line(p_deptno||'该部门不存在,请输入正确的部门号。');
  end if;
  if w!=0 and e!=0 then
     select deptno into v_deptno  from emp 
       where empno=p_empno;
     update emp  set deptno=p_deptno where empno=p_empno; 
    --commit;  
   dbms_output.put_line('员工由'||v_deptno||'号部门调入调入'||p_deptno||'号部门');
  else
    null;
  end if;

end;

select * from emp;
call we1(3578,21);

/9.(9)创建一个存储过程,以一个整数为参数,
输入工资最高的前几个
(参数值)员工的信息。
/

create or replace procedure we1 (p_no in int)
is
v_ename emp%rowtype;
cursor we is
select rownum w,e.* from
(select * from emp order by sal desc) e;
begin
for sd in we loop
if sd.w<=p_no then
dbms_output.put_line
(‘工资第’||sd.w||‘的是’||sd.ename||’__’||sd.empno);
end if;
end loop;
end;

–第二种
create or replace procedure we1 (p_no in int)
is
cursor we is
select * from (
select rownum w,e.* from
(select * from emp order by sal desc) e)
where w<=p_no;
begin
for sd in we loop
dbms_output.put_line
(‘工资第’||sd.w||‘的是’||sd.ename||’’||sd.empno);
end loop;
end;
–调用
call we1(5);
/*10. 创建一个存储过程,以两个整数为参数,
输出工资排序在两个参数之间的员工信息。 /
create or replace procedure
we1 (p_no in int,p_no1 in int)
is
cursor we is select rownum w,e.
from
(select * from emp order by sal desc) e;
begin
for sd in we loop
if sd.w between p_no and p_no1 then
dbms_output.put_line(sd.ename||’
’||sd.empno);
end if;
end loop;
end;

你可能感兴趣的:(PL/SQL块)