存储过程和存储函数
存储在数据库中供所有用户程序调用的子程序叫存储过程、存储函数。两者的相同点是:完成特点功能的程序。区别是:存储函数可以使用return语句返回值,存储过程不可以。存储过程的有点:
- 执行速度更快
- 允许模块化程序设计
- 提高系统安全性
- 减少网络流通量
系统存储过程存放在master数据库中,名称都以sp_开头或xp_开头,类似Java语言类库中的方法:
系统存储过程 | 说明 |
---|---|
sp_databases | 列出服务器上的所有数据库 |
sp_helpdb | 报告有关指定数据库或所有数据库的信息 |
sp_renamedb | 更改数据库的名称 |
sp_tables | 返回当前环境下可查询的对象的列表 |
sp_columns | 返回某个表列的信息 |
sp_help | 查看某个表的所有信息 |
sp_helpconstraint | 查看某个表的约束 |
sp_helpindex | 查看某个表的索引 |
sp_stored_procedures | 列出当前环境中的所有存储过程 |
sp_password | 添加或修改登录账户的密码 |
sp_helptext | 显示默认值、未加密的存储过程、用户定义的存储过程、触发器或视图的实际文本 |
一、创建和使用存储过程
- 用create procedure命令建立存储过程
1 | SQL> create [or replace] procedure 过程名[(参数列表)] |
第一个存储过程:打印hello world
1
2
3
4
5
6
7SQL> create or replace procedure SAYHELLOWORLD
as --oracle存储数据库对象默认采用大写,所以保存的过程名全大写
--说明部分(包括声明光标等)
begin
dbms_output.put_line('Hello World');
end;
/调用该存储过程
1
2
3
4
5
6
7--调用方式1
SQL> exec SAYHELLOWORLD();
----调用方式2
SQL> begin
SAYHELLOWORLD();
end;
/
带参数的存储过程
例:为指定的员工涨100块钱工资,并打印涨前和涨后的工资
1
2
3
4
5
6
7
8
9
10
11
12
13
14SQL> create or replace procedure RAISESALARY(eno in number) --输入参数
as
--定义一个变量保存涨前的薪水
psal emp.sal % type;
begin
--得到员工涨前的薪水
select sal into psal from emp where empno = eno;
--涨薪水操作
update emp set sal = sal + 100 where empno = eno;
--可以commit和rollback
--一般不在存储过程或存储函数中commit或rollback,因为这样不能保证调用者在同一个事务中
dbms_output.put_line('涨前:'|| psal || '涨后:' || (psal+100));
end;
/调用该存储过程
1
2
3
4
5
6SQL> begin
RAISESALARY(7839);
RAISESALARY(7840);
commit;
end;
/
调用存储过程
不推荐远程调试(指oracle数据库与图形化工具不在同一机器上),这样远程调试需要指定服务器的IP地址,还需要工具-首选项-调试器-端口
推荐把图形化工具拷贝到虚拟机所在的服务器的IP地址上
授权
1
2SQL> / as sysdba;--不用写用户名和密码,采用主机认证
grant debug connect session,debug any procedure to scott;
二、存储函数
函数(Function)命名的存储程序,可带参数,并返回一计算值。存储函数和存储过程的结构类似,但必须有一个return子句用于返回函数值
创建存储函数的语法
1
2
3
4SQL> create [or replace] function 函数名[(参数列表)]
return 函数值类型
as
pl/sql子程序体;例:查询某个员工的年收入
1
2
3
4
5
6
7
8
9
10
11
12SQL> create or replace function QUERYEMPINCOME(eno in number)
return number
as
--定义员工的薪水和奖金变量
psal emp.sal % type;
pcomm emp.comm % type;
begin
--得到该员工的月薪和奖金
select sal,comm into psal,pcomm from emp where empno = eno;
return psal*12+nvl(pcomm,0);
end;
/
三、out参数
存储过程和存储函数都可以有多个out参数,存储过程可以通过out参数来实现返回值。原则:如果只有一个返回值,则使用存储 函数,否则使用存储过程。例:查询某个员工姓名、月薪和职位:
1 | SQL> create or replace procedure QUERYEMPININFO(eno in number, |
分析:
查询某个员工的所有信息–out参数太多?
查询某个部门中所有员工的所有信息–out参数中返回集合?
如何解决:在out参数中使用光标
四、out参数使用光标
查询某个部门中所有员工的所有信息:
1 | --包头:只负责声明ref---引用, |
在应用中实现
1 | //在应用中访问包中的存储过程 |
五、java访问存储过程
数据库工具类
1 | /** |
访问存储过程
1 | import org.junit.Test; |
六、java访问存储函数
访问存储函数
1 | import org.junit.Test; |