09.Oracle中的存储过程与存储函数

Oracle中的存储过程与存储函数

以下演示使用拥有dba权限的用户,复用scott用户中的部分表;

一、存储过程

存储过程: (Stored Procedure) 在大型数据库系统中,存储过程是一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。

简单来说,存储过程是提前已经编译好的一段pl/sql语言,放置在数据库端可以被直接调用。这一段pl/sql一般都是固定步骤的业务。

1). 语法介绍

create [or replace] procedure 过程名[( 参数名 in/out  数据类型,...)]
is -- 或者使用 `as`
    变量声明;
begin
    PLSQL 子程序体;
end [过程名];

2). 存储过程案例

可在PL/SQL工具右侧Procedure看到创建的存储过程;如果创建出现问题,相关图标左上方会有一个红叉

  1. 创建存储过程
-- 给指定员工涨100块钱
-- 新建或者覆盖;in的位置表示传入的参数,如果写为out为传出的参数,如果不写默认in
create or replace procedure p1(eno in emp.empno%type)
is -- 可以换成 as

begin
  update emp set sal = sal + 100 where empno = eno;
  commit;
end;
  1. 测试p1存储过程
select * from emp where empno = 7788;

declare

begin
   p1(7788);
end;

3). out类型参数详解

规律: 凡是涉及到 into查询语句赋值(或者间接) 或者 :=赋值 操作的形参,都用out来修饰;

注意: xxx%type复用类型这样方式会根据使用的场景自动判断是否去除长度;比如在形参声明会自动去除,在自定义变量不会去除;

  1. 创建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;
  1. 测试out类型的存储过程
declare
    n number(10);
begin
    p_yearsal(7788, n); -- 第一个为传入的形参,第二个是传出的形参
    dbms_output.put_line(n);
end;

二、存储函数

存储函数与存储过程很类似

1). 语法以及注意事项

1. 语法介绍

create or replace function 函数名(var1 in[/out] type, var2 in[/out] type, ...) return 数据类型
is
    结果变量  数据类型;
begin
    return(结果变量);
end [函数名];

2. 注意事项

  1. 存储过程和存储函数的参数(形参)不能带长度 比如number(10)这种
  2. 存储函数的返回值类型不能带长度
  3. 自定义的变量(非形参)可以带上长度

2). 案例演示

工具右侧Functions可以看到创建的存储函数;

  1. 通过存储函数实现计算指定员工的年薪
-- 这里的%type自动将长度去除,当然可以传入多个形参,in/out规则同存储过程一样
create or replace function f_yearsal(eno in 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;
  1. 测试f_yearsal

调用存储函数的时候,返回值需要接收

declare
   s number(10);
begin
   s := f_yearsal(7788);
   dbms_output.put_line(s);
end;

三、存储过程 和 存储函数的区别

1). 区别介绍

  1. 语法区别:

    1. 关键字不一样,
    2. 存储函数比存储过程多了两个return
  2. 本质区别: 存储函数有返回值,而存储过程没有返回值

如果存储过程向实现由返回值的业务,需要使用out修饰的形参为调用者传入的参数赋值;即便是存储过程使用了out类型的参数,其本质也不是真的有了返回值,而是在存储过程内部给out类型的参数赋值,在执行完毕后,直接拿到输出类型参数的值;有些需要返回值的应用场景,使用存储过程是无法做到的,如下案例;

  1. 相同点:都可以通过 out 指定一个或多个输出参数

2). 案例演示

可以使用存储函数有返回值的特性,自定义函数,就像java语言中的函数那样使用(存储过程不能用于自定义函数)

  1. 案例准备:准备 emp员工表和dept部门表, copy scott用户的表
create table emp as select * from scott.emp;
create table dept as select * from scott.dept;
  1. 使用【存储函数】实现一个函数功能:提供部门编号,输入一个部门名称
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;
  1. 联合使用自定义函数进行查询:查询员工姓名(emp表),以及员工所在部门名(dept表);
select e.ename, fdna(e.deptno)
from emp e;
  1. 补充:传统实现方式
select e.ename, d.dname
from emp e, dept d
where e.deptno = d.deptno;

你可能感兴趣的:(09.Oracle中的存储过程与存储函数)