Oracle --存储过程

创建语法:
     CRATE [OR REPLACE] PROCEDURE<过程名>
           (<参数1>,[方式1]<数据类型1>,
            <参数2>,[方式2]<数据类型2> 
           
          ... )
          IS|AS
          PL/SQL过程体;
          
参数类型
  输入和输出、输入即输出参数
  A)输入参数
    在过程执行中,如果需要从外部传入数据执行过程,需要提供执行的时候提供输入参数。
		参数命名:in
  B)输出参数
		在获得输入参数执行过程的时候,如果需要获得过程的返回,需要提供输出参数来进行数据
		的返回。
		参数命名:out
  C)输入即输出: in out 
在执行过程的操作中,作为参数输入的操作中,过程将其参数输入数据进行处理后,需要原方式返回给执行者操作的时候,需要在输入参数的基础上将其定义成输出参数。
参数命名:in out
--数据准备
create table t_dept as select *  from dept;
--完整示例:
-- 通过存储过程添加新部门到t_dept表中
-- loc varchar2 :='New York' 指定默认值
create or replace procedure new_dept
  (d_name in varchar2,loc in  varchar2 )
 is
   dept_no number;
  begin 
     -- 先得到当前部门表的最大部门编号
     select max(deptno) into dept_no from t_dept; 
     --在当前最大部门编号的基础上+10作为新部门的部门编号
     dept_no:=dept_no+10;
     --将数据添加到部门表中
     insert  into t_dept values (dept_no,d_name,loc) ;
     commit;
     exception 
        when others then 
        dbms_output.put_line('新增部门失败');
end ;

--调用存储过程
declare
  dname varchar2(30):='研发部';
  loc varchar2(30):='北京';
begin
    new_dept(dname, loc);
    --new_dept(dname);
end;

--删除存储过程
drop procedure new_dept;
/*
in参数类型 这是个输入类型的参数,表示这个参数值输入给过程,供过程使用
*/ 
--完成将一个数成倍增加
create or replace procedure e_double(in_num in number,out_num out number)
as
begin
       out_num:=in_num*2;
end;

declare
   vnum number:= 20;
   vresult number;
begin
      e_double(vnum, vresult);
      dbms_output.put_line(vresult);   
end;
/*
out参数类型 这是个输出类型的参数,表示这个参数在过程中被赋值,可以传给过程体以外的部分或环境
in out参数类型  这种参数类型其实是综合了上述两种参数类型,既向过程体传值,在过程体中也被赋值
而传向过程体外
*/
--示例:根据部门编号得到部门名称和该部门的平均工资
create or replace  procedure dept_sal 
  (deptinfo in out varchar2,avgsal out number)
 is 
  dept_no number; -- 声明变量
begin
       dept_no :=to_number(deptinfo); -- 得到部门编号参数
       select  dname into deptinfo from dept where deptno=dept_no; -- 将参数设置为部门名称
       select avg(sal) into avgsal from emp where deptno=dept_no; -- 得到部门的平均工资
end;

declare 
  d_name varchar2(20);
  avg_sal number;
begin
  d_name:='&部门编号';
  dept_sal(d_name,avg_sal);
  dbms_output.put_line('部门名称:' || d_name|| ',平均工资:' ||avg_sal);
end;
--存储过程综合案例(返回指定部门的员工信息:编号,姓名,部门编号,部门名称,工资,员工所在部门平均工资)

/*
1.创建视图
2.创建存储过程(返回结果集的游标 c_empavg out sys_refcursor)
3.调用存储过程 输入编号,获得结果集(c_empavg)
4.循环游标,打印提示信息
*/
 
--创建视图
create or replace view vi_emp_avgsal(empno,ename,deptno,dname,sal,avgsal)
as 
select a.empno,a.ename,a.deptno,a.dname,a.sal,b.avgsal from
(select e.empno,e.ename,e.deptno,d.dname,e.sal from emp e,dept d where e.deptno=d.deptno) a,
(select deptno,round(avg(sal),2) as avgsal from emp group by deptno) b
where a.deptno = b.deptno;


select * from vi_emp_avgsal;


--创建存储过程(返回结果集的游标 c_empavg out sys_refcursor)
--游标做输出参数时,类型为sys_refcursor
create or replace procedure p_emp_avgsal(v_deptno in number,c_empavg out sys_refcursor)
as 
  e_deptno exception;
begin
  if v_deptno<0 then
    raise e_deptno;
  end if;
  open c_empavg for 'select * from vi_emp_avgsal where deptno =:v_temp_deptno' using v_deptno;
exception 
  when e_deptno then
     dbms_output.put_line('e_deptno exception ');
     when others then
       dbms_output.put_line('unkonw error exception ');
end;

--调用存储过程
declare
  type t_empavg is ref cursor;
  c_empavg t_empavg;
  v_avgsalrow vi_emp_avgsal%rowtype;
  v_deptno number;
begin
  v_deptno :='&请输入部门编号:';
  p_emp_avgsal(v_deptno,c_empavg);
  loop
      fetch c_empavg into v_avgsalrow;
      exit when c_empavg%notfound;
      dbms_output.put_line('v_avgsalrow.deptno '||v_avgsalrow.deptno);
      dbms_output.put_line('v_avgsalrow.avgsal '||v_avgsalrow.avgsal);
  end loop;
  if c_empavg%isopen then
    close c_empavg;
  end if;
exception 
  when others then
       dbms_output.put_line('unkonw error exception ');
end;




1.假设有张学生成绩表如下:
[姓名][学科][成绩]
 张三  语文   80
 张三  数学   86
 张三  英语   75
 李四  语文   78
 李四  数学   85
 李四  英语   78
现有需求如下 :
(1)要求根据姓名,把各科成绩显示在一条记录里。显示结果如下:
姓名      语文    数学   英语   总成绩
--------------------------------------------------
李四       78      85     78      241
张三       80      86     75      241
总分      158      171    153     482
使用存储过程实现


--行转列 case when
--多表连接查询 扩充列
--union 关键字 行结果集相加(扩充行)

create or replace view vi_st_sc(name,chinese,math,english,totalscore)
as(
select name,
sum(case when subject='语文' then score else 0 end) as chinese,
sum(case when subject='数学' then score else 0 end) as math,
sum(case when subject='英语' then score else 0 end) as english,
sum(score) as totalscore
from student group by name
)

--利用视图查询结果集
select name,chinese,math,english,totalscore from vi_st_sc
union
select '总分',sum(chinese),sum(math),sum(english),sum(totalscore) from vi_st_sc;

create or replace procedure pr_stu_in(var_cur out sys_refcursor)
is 
begin
  open var_cur for 
  select name,chinese,math,english,totalscore from vi_st_sc
  union
  select '总分',sum(chinese),sum(math),sum(english),sum(totalscore) from vi_st_sc;
exception
  when others then
    dbms_output.put_line('unkonw error exception ');
end;    

declare 
    type ref_cursor is ref cursor;
    c_student ref_cursor;
    v_studet vi_st_sc%rowtype;
begin
    pr_stu_in(c_student);
    loop
      fetch  c_student into v_studet;
      exit when c_student%notfound;
       dbms_output.put_line('v_studet.chinese '||v_studet.chinese||' v_studet.math '||v_studet.math);
    end loop;
    if c_student%isopen then
      close c_student;
    end if;
end;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值