存储过程,函数都是数据库的对象。
创建和调用
存储在数据库中的子程序,是由plsql语言写的,完成特定功能的程序。
函数可以返回值,存过不能返回值。除此之外,一致。
create procedure 过程名(参赛列表)
as
plsql子程序
打印一helloWorld
create or replace procedure sayhelloworld
as
--说明部分
begin
dbms.output_line(hello world);
end;
调用存储过程的方式一:
execute/exec sayhelloworld
二:
begin
sayhelloworld();
sayhelloworld();
set serveroutput on;
create or replace procedure 过程名(参数列表)
as
begin
end;
/
创建带参数的存储过程
为指定的员工,涨100元薪水,并打印涨前和涨后的薪水?
create or replace procedure raisesaly(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;
dbms_output_line(涨前:||psal||涨后||psal+100));
一般不在存过中,函数中,提交回滚,不能保证提交,会在同一个事务中。
如何来涨工资:
raisesal(7899);
raisesal(9999);
commit;
end;
/
输入参数in 输出参数out
不推荐远程调试
推荐本地调试(可以在生产机上虚拟机)
数据库所在的服务器在同一个机器上
调试存过:
可进行调试么?
编译以进行调试--图标变化。
sum(a=1,b=2)赋值方式
打断点,程序停在断点的位置上(权限问题,具备调试的权限)
管理员授权
sqlplus /as sysdba;
grant ... to...
f8单步运行
存储函数
可带参数,并返回一个计算值,也是一个命名的存储程序
结构类似,必须有一个return 值
create or replace function 函数名(参数列表)
return 返回类型
as
begin
end;
/
--查某个员工的年收入
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+pcomm;
end;
/
return 函数
可以远程调用set linesize 1000;
null值的情况下,相加为null,
nvl(pcomm,0);
out参数:
存过没有返回值。
过程和函数都可以通过out指定一个,多个out参数,可以out参数实现返回值。
查下某个员工的姓名 月薪和职位
create or replace procedure queryempinfom(emo in number,pename out varchar2,psal out number,pjob out varchar2)
as
begin
得到该员工的姓名,月薪和职位
select ename,sal,empjob into pename,pasl,pjob from emp where empno = eno;
end;
/
out中返回一个集合?
out参数太多?
集合当中只有一行。
app中访问和调用存过和存函
Java中访问和调用数据库中的子程序
Connection
Statement:sql语句运行的环境
CallableStatement:子接口
myslq和oracle的调用标准是一致的
调用存过:
{call[(,,...)]}
{call queryempinfom(?,?,?,?)}
conn.prpareCall(sql);
对于输入参数需要赋值?
对于输出参数在调用之前是没有值的,需要声明;
call.registerOutParameter(2,sqlType);--OracleTypes.VARCHAR);把数据库的类型转为Java类型。
...
执行调用
call.execute();--out参数就有返回值了
取出结果
call.getString(2);
call.getDouble(3);
call.getString(4);
打印看一看
访问存函:
{?=call[(arg1),,...)]}
{?=call queryempincome(?)}
call = conn.prepreCall(sql);
对中输出参数,声明
call.registerParameter(1,OracleTypes.NUMBER);
对于输入参数,赋值
call.setInt(2,8888);
call.execute();
执行以后,就取出结果集。
out参数中使用光标
声明包结果
包头
包体
某个部门中,所有员工的所有信息
create or replace package mypackage as
type empcursor is fef cursor;
procedure queryEmpList(dno in number,empList out empcursor);
end mypackage;
包体需要实现包头所有声明的所有方法
包体:
create or replace package body mypackage as
procedure queryEmpList(dno in number, empList out empcursor) as
begin
open empList for select * from emp where deptno = dno;
end queryEmpList;
end mypackage;
光标在使用前要打开。
Java程序中调用包
{call[,,....]}
{call mypackage.queryEmplist(?,?)}
call = conn.prepareCall(sql);
对于输入参数,需赋值
对于输出参数,需声明
call.registerOutParameter(2,OracleTypes.CURSOR);
call.execute();
取出该部门中的所有员工的信息:
rs = ((OracleCallableStatement)call).getCursor(2);
while(rs.next()){
}
领取专属 10元无门槛券
私享最新 技术干货