存储过程和函数 也是一种pl/sql块,是存入数据库的pl/sql块。但和pl/sql不同的是,存储过程和函数是以命名的方式存储于数据库中的,pl/sql程序叫“无名块”。
存储过程和函数以命名的数据库对象形式存储于数据库中。这样一来代码就不用保存在本地,用户可以在任何客户机上登录到数据库,并调用或修改代码。(由数据库提供安全保证)
- 存储过程和函数的信息都写入了数据字典。
- 一个重复使用的功能,可以设计成存储过程。比如:一个经常调用的计算,可以设计成存储函数。根据雇员编号返回雇员的姓名,可以设计成存储函数。显示一张工资统计表,可以设计成存储过程。
创建存储过程:
- 创建存储过程,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系统权限。该权限可由系统管理员授予。
- 编写存储过程可以使用任何文本编辑器或直接在SQLPlus环境下进行,编写好的存储过程必须要在SQLPlus环境下进行编译,生成编译代码,原代码和编译代码在编译过程中都会被存入数据库。编译成功的存储过程就可以在Oracle环境下进行调用了。
create or replace procedure 存储过程名字(arg1,arg2...) -- 定义参数时,只能指定数据类型,不能指定数据长度。
is -- 用于开始pl/sql代码块。
begin
PL/SQL Block;
end(存储过程名字);
删除存储过程:
drop procedure procedure_name;
编译存储过程:
alter procedure procedure_name compile;
查看存储过程的代码:
select text
from user_source
where name = procedure_name
调用存储过程:
-- 方法1:
execute 模式.存储过程名(arg...);
-- 方法2:
begin
模式.存储过程名(arg...);
end;
- 传递的参数必须与定义的参数类型、个数和顺序一致(如果参数定义了默认值,则调用时可以省略参数)。参数可以是变量、常量或表达式,用法参见下一节。
- 如果是调用本账户下的存储过程,则模式名可以省略。要调用其他账户编写的存储过程,则模式名必须要添加。
参数传递
参数的作用是向存储过程传递数据,或从存储过程获得返回结果。正确的使用参数可以大大增加存储过程的灵活性和通用性。
参数的类型有三种:
in:
参数名 in 数据类型 default 值;
定义一个输入参数变量,用于传递参数给存储过程。在调用存储过程时,主程序的实际参数可以是常量、有值变量或表达式等。DEFAULT 关键字为可选项,用来设定参数的默认值。
out:
参数名 out 数据类型;
定义一个输出参数变量,用于从存储过程获取数据,即变量从存储过程中返回值给主程序。在存储过程中,参数变量只能被赋值而不能将其用于赋值,在存储过程中必须给输出变量至少赋值一次。
in out:
参数名 IN OUT 数据类型 DEFAULT 值
在存储过程中,变量接收主程序传递的值,同时可以参加赋值运算,也可以对其进行赋值。在存储过程中必须给变量至少赋值一次。
如果省略IN、OUT或IN OUT,则默认模式是IN
---编写存储过程函数,当传入一个部门编号后,根据该部门不同的薪资进行加薪
-- <= 900加薪1000
-- <= 1500 加薪800
-- 否则加薪600
create or replace procedure pro_addSalary(dno emp.deptno%type)
is
begin
declare
cursor emp_cursor is select * from emp where deptno = dno;--声明游标
v_cursor emp_cursor%rowtype;--声明游标变量
begin
open emp_cursor;--打开游标
loop--遍历游标
fetch emp_cursor into v_cursor; --提取游标中的数据,每次取一行赋值到变量中
exit when emp_cursor%notfound; --编写退出循环条件
if v_cursor.sal <= 900 then --判断薪资范围
--更新该员工的薪资
update emp set sal = sal + 1000 where empno = v_cursor.empno;
end if;
if v_cursor.sal > 900 and v_cursor.sal <= 1500 then
update emp set sal = sal + 800 where empno = v_cursor.empno;
end if;
if v_cursor.sal > 1500 then
update emp set sal = sal + 600 where empno = v_cursor.empno;
end if;--这个容易忘记!!!
end loop;--有打开就有关闭
close emp_cursor;--关闭游标
end;
end;
select * from emp where deptno = 20
---- 调用存储过程(加薪)
begin
pro_addSalary(20);
end;