过程
过程用于执行特定的操作 当建立过程时 既可以指定输入参数(in) 也可以指定输出参数(out) 通过在过程中使用参数 可以将数据传递到执行部分
通过使用输出参数 可以将执行部分的数据传递到应用环境 在sqlplus中可以使用create procedure 命令来建立过程
exec 过程名(参数)
call 过程名(参数)都可以调用过程
过程的进一步讲解
oracle过程 可以指定参数是输入的参数 还是输出的参数 基本语法如下
create procedure 过程名 (变量名 in 变量类型 ...变量名 out 变量类型) is
//定义变量
begin
//执行语句
end;
/
//如果存在就替换
create or replace procedure pro5(in_ename in varchar2 ,in_new_sal in number ) is//只指定类型 不用指定大小 定了大小就出错
begin
update emp sal = in_new_sal where ename=in_ename;
end;
/
show error; 默认不打印错误 输入后打印错误
当我们编写过程 中可以输入sho error; 来显示具体的错误信息
exec pro5('SMITH',10);
如何在java程序中调用一个存储过程
Connection ct = null;
CallableStatement cs = null;
try {
//加载驱动
// Class.forName("oracle.jdbc.driver.OracleDriver");
// //得到连接
// ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","scott","m123");
// //创建CallableStatement 接口引用对象
// cs = ct.prepareCall("{call pro(?,?)}");
// // 给?幅值
// cs.setString(1, "SMITH");
// cs.setFloat(2, 45.2f);//可以不加f oracle会尝试帮你转成指定的类型 成功就运行
// //执行语句
// cs.execute();
//需要时去调用 如果不是抛运行时 异常 那么就要捕获异常或抛
String sql = "{call pro5(?,?)}";
String paras [] = {"KING","8000"};
SQLHelper.executeProcedure(sql, paras);
} catch(Exception e){
e.printStackTrace();
} finally{
//关闭资源
}
或者在SQLHelper 升级
public static void executeProcedure(String sql , String[] parameters){
try {
ct = DriverManager.getConnection(url,username,password);//得到连接
ps = ct.prepareCall(sql);
if(parameters!=null&&"".equals(parameters)){//更加严谨
for (int i = 0; i < parameters.length; i++) {
ps.setString(i+1, parameters[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
} finally{
close(rs,ps,ct);
}
}
函数 函数用于返回特定的数据 当建立函数时 在函数头部必须包含return子句 而在 函数体内必须包含return语句 返回的数据
我们可以使用create function 来建立函数
create function 函数名(参数1... )
return 数据类型 is
定义变量;
begin
执行语句;
end;
在sqlplus 中调用函数 var 变量名 变量类型
call 函数名(参数值) into ; 变量名;
print 变量名
同样可以在java程序中调用函数
select annual_inconme('SCOTT') from dual;
如何在存储过程中 返回一个结果 (这个结果可能是一个简单的值 也可能是一个集合)
create function fun1(in_v_ename varchar2)
return number is
--定义一个变量来接受年薪
v_annual_sal number;
begin select (sal+nvl(comm,0))*13 into v_annual_sal from emp where ename =in_v_ename;
return v_annula_sal;
end;
/
如何调用函数
1、在控制台调用select 函数名(实际参数) from dual 一般都用 虚表 函数中已经查表了
2、在java中调用
//如何在java调用自己编写的函数
public static void main(String[] args) {
//可以取别名 fun1('SMITH') annual
String sql = "select fun1('SMITH') from dual";//用虚表 因为函数自身带有查表 如果再from表 就会查表的行数
ResultSet rs = SQLHelper.executeQuery(sql, null);
try {
if(rs.next()){
System.out.println(rs.getDouble(1));//返回第一行内容 查找结果从第一行开始
}
} catch (SQLException e) {
e.printStackTrace();
}
}
包
包用于在逻辑上组合过程和函数 它由包规范 和包体两部分组成
我们可以使用create package 来创建包
create or replace package 包名 is
procedure 过程名(变量名 变量类型...);
function 函数名(变量名 变量类型...) return 数据类型;
end;
/
为什么需要包 因为 使用包可以更好的管理自己写的函数和过程
包的规范只包含了过程和函数的说明 但是没有过程和函数的实现代码 包体用于实现包规范中的过程和函数
create [or replace] package 包名 is
-- 声明函数
function 函数名(参数1) return 返回类型;
--声明过程
procedure 过程(参数1)
end;
/
create or replace package mypackage1 is
procedure pro1(v_in_ename varchar2,v_in_newsal number);
function fun1(v_in_ename varchar2) return number;
end;
/
建立包体 可以使用 create package body 命令
create or replace package body 包名 is
procedure 过程名(变量名 变量类型...) is
begin
执行语句;
end;
function 函数名(变量名 变量类型...) //如果在包里面没声明过不能加入
return 数据类型 is
begin
执行语句;
end;
end;
create or replace package body mypackage1 is
procedure pro1(v_in_enanme varchar2 , v_in_newsal varchar2) is
begin
update emp set sal = v_in_newsal where ename = v_in_ename;
end;
function fun1(v_in_ename varchar2) return number is
v_annual_sal number; 要返回变量 不然无法更新
begin
select (sal+nvl(comm,0))*13 into v_annual_sal from emp where ename =v_in_ename;
return v_annual_sal;
end;
end;
/
exec mypackage1.pro1('SMITH',2);