过程是用于完成特定任务的子程序
案列1:通过输入员工编号,显示名字(in)
create or replace procedure find_emp(emp_no number := &eno) as empname varchar2(30); begin select ename into empname from emp where empno=emp_no; dbms_output.put_line(‘雇员的姓名是:‘||empname); exception when no_data_found then dbms_output.put_line(‘雇员编号未找到‘); end find_emp; |
案列:编写一个简单的Oracle存储过程,要求根据部门编号显示出其所有员工
create or replace procedure p_search(eno in number) as cursor mc is select ename from emp where deptno=eno; v_ename emp.ename%type; begin open mc; loop fetch mc into v_ename; exit when mc%NOTFOUND; dbms_output.put_line(v_ename); end loop; end; call p_search(10); |
案列2:将输出的值也定义在设置成形参(out)
--通过输入员工编号,显示名字 create or replace procedure p_search(eno in number,v_ename out varchar2) is begin select ename into v_ename from emp where empno=eno; if sql%FOUND then dbms_output.put_line(‘编号:‘||eno||‘ 姓名:‘||v_ename); end if; exception when no_data_found then dbms_output.put_line(‘没有该数据类型‘); end; --调用过程 declare v_name varchar2(30); begin p_search(7788,v_name); end; |
案列3:通过输入员工编号,显示薪水(in out)
--通过输入员工编号,显示薪水(in out) create or replace procedure p_search(eno in out number) as begin select sal into eno from emp where empno=eno; exception when no_data_found then dbms_output.put_line(‘没有该员工‘); end; declare v_eno number; begin v_eno := 7788; p_search(v_eno); dbms_output.put_line(v_eno); end; |
函数:执行操作并返回值
案列:接收部门的编号作为参数,返回该部门的最高工资的员工姓名
create or replace function get_name(dno in number) return varchar2 as v_ename varchar2(30); begin select ename into v_ename from emp e where e.sal=(select max(sal) from emp where deptno=dno); if sql%FOUND then return v_ename; end if; end; declare v_name varchar2(30); begin v_name:=get_name(10); dbms_output.put_line(v_name); v_name:=get_name(20); dbms_output.put_line(v_name); end; |
案列4:实现添加员工
--为部门表添加一个字段maxnum,整型 alter table dept_temp add(maxnum number); select * from dept_temp order by deptno asc; update dept_temp set MAXNUM=5 where deptno=10; update dept_temp set MAXNUM=10 where deptno=20; update dept_temp set MAXNUM=8 where deptno=30; update dept_temp set MAXNUM=3 where deptno=40; |
--创建过程 create or replace procedure add_emp(p_emp emp%rowtype) is v_emp_count number; v_dept_count number; full_result exception;--定义异常 begin select count(*) into v_emp_count from emp where deptno=p_emp.deptno; select maxnum into v_dept_count from dept_temp where deptno=p_emp.deptno; if v_emp_count<v_dept_count then insert into emp_temp values(p_emp.empno,p_emp.ename,p_emp.job, p_emp.mgr,p_emp.hiredate,p_emp.sal,p_emp.comm,p_emp.deptno); dbms_output.put_line(‘录入成功‘); else raise full_result; end if; exception when full_result then dbms_output.put_line(‘该部门人数编制已满,不能再添加员工‘); end; |
--创建过程,测试过程add_emp编译是否成功 create or replace procedure call_addemp is v_emp emp%rowtype; begin select * into v_emp from emp where empno=7788; v_emp.empno:=7789; add_emp(v_emp); end; |
--测试过程是否成功 call call_addemp(); |
过程和函数的比较
过程 |
函数 |
作为pl/sql语句执行 |
作为表达式的一部分调用 |
在规格说明中不包含return子句 |
必须在规格说明中包含return子句 |
不返回任何值 |
必须返回单个值 |
可以包含return语句,但是与函数不同,它不用于返回值 |
必须包含一条return语句 |
程序包:是对相关过程、函数、变量、游标和异常等对象的封装,由规范和主体组成
优点:
- 模块化
- 更轻松的应用程序设计
- 信息影藏
- 新增功能(过程可以重载,可以定义公用变量或游标)
- 性能更佳
案列1:编写一个过程:将表中的员工名字调用出来
一个函数:给部门号,将该部门中的最高工资的员工姓名显示出来
--创建包规范 create or replace package pk_test is v_ename varchar2(30); --pro_1 procedure pro_1; --get_name function get_name(dno in number) return varchar2; end pk_test; |
--创建包主体 create or replace package body pk_test is procedure pro_1 is cursor mc is select * from emp; v_emp emp%rowtype; begin open mc; loop fetch mc into v_emp; exit when mc%notfound; dbms_output.put_line(‘姓名:‘||v_emp.ename||‘ ,薪水:‘||v_emp.sal); end loop; close mc; end pro_1;
function get_name(dno in number) return varchar2 is v_ename varchar2(30); begin select ename into v_ename from emp e where e.sal=(select max(sal) from emp where deptno=dno); if sql%FOUND then return v_ename; end if; end get_name; end pk_test; |
--测试过程pro_1 call pk_test.pro_1(); --测试函数get_name declare v_name varchar2(30); begin v_name :=get_name(10); dbms_output.put_line(v_name); end; |
案列2:
--创建程序包 --增加部门信息的函数,删除部门信息的函数,查询部门信息的过程
--创建包规范 create or replace package pk_test is deptrec dept%rowtype; --add_dept function add_dept( dept_no number, dept_name varchar2, dept_loc varchar2) return number;
--delete_dept function delete_dept(dept_no number) return number;
--query_dept procedure query_dept(dept_no in number); end pk_test;
|
--创建包主体 create or replace package body pk_test is function add_dept( dept_no number, dept_name varchar2, dept_loc varchar2) return number is begin insert into dept values(dept_no,dept_name,dept_loc); if SQL%FOUND then return 1; end if; end add_dept;
function delete_dept(dept_no number) return number is begin delete dept where deptno=dept_no; if SQL%FOUND THEN return 1; end if; end delete_dept;
procedure query_dept(dept_no in number) is begin select * into deptrec from dept where deptno=dept_no; exception when no_data_found then dbms_output.put_line(‘部门表中没有你输入的部门‘); end query_dept; end pk_test; |
--测试 select * from dept; declare v_num number; begin v_num := pk_test.add_dept(80,‘教学不‘,‘长沙‘); if v_num = 1 then dbms_output.put_line(‘增加成功‘); end if; end; |