最经这段时间在学习Oracle中的PL/SQL了,其中存储过程和游标的使用应该算是比较重要的东西了。在周日的下午,突然想写点东西,刚好把自己这段 时间的学习感悟写写吧。一者可以总结自己的学习,二者希望可以可以给其它学习的人提供一点帮助。我也仅仅是一名Java学习菜鸟。还望各位大神级别的人要 是看到了不准批斗小弟。好了,废话不多说了。切入正题吧。
假设我们需要通过JDBC连接Oracle数据库,暂时就拿Oracle数据库自带的表emp(scott模式下的)表和dept表。根据我们输入的一个部门标号dno,类型为number,输出该部门下的所有员工的编号和员工姓名。
第一种存储过程的使用方法:
思路如下:
1:新建一个Packages,例如名称为:first_package
2:再实现一个package bodies,注意了其名称必须和packages的名字相同,因为其是对packages的实现吗,正如java中接口的实现一样。所以名称也为:first_package
3:Java中调用存储过程。
代码如下:
定义一个package:
create or replace packagefirst_package is
-- Public type declarations
type mycur is ref cursor;
procedure proc_cur(dno in number,cur out mycur);
end first_package;
实现package
create or replace package body first_packageis
--注意此处无begin
procedure proc_cur(dno in number,cur out mycur)
as
begin
open cur for select * from emp where emp.deptno=dno;
end proc_cur;
end test_package;
Java中调用存储过程:
定义一个DBUtils工具类
package com.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 获取Connection等连接的工具类
* @author Administrator
*/
public class DBUtils {
Connection conn=null;
//url和user,password
Stringurl="jdbc:oracle:thin:@192.168.19.39:1521:orcl";
String user="scott";
String password="tiger";
//获得连接对象Connection
public Connection getConnection(){
//加载驱动
StringoracleDriver="oracle.jdbc.driver.OracleDriver";
try {
Class.forName(oracleDriver);
//获得连接
conn=DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//关闭Connection对象
public void closeConn(Connection conn){
if(conn!=null){
try {
conn.close();
} catch (SQLExceptione) {
e.printStackTrace();
}
}
}
}
测试类:
package com.jdbc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.OracleTypes;
/**
* 测试类
* @author Clark
*
*/
public class JdbcTest {
static DBUtils db=new DBUtils();
static Connection conn=null;
public static void main(String[] args) {
try {
//获得连接对象
conn=db.getConnection();
//获得调用存储过程的对象
CallableStatementcstm=getCallableStatement(conn);
//设置参数值
cstm.setInt(1, 20);
//因为存储过程中定义第二个参数为out,而且其类型为游标型
cstm.registerOutParameter(2, OracleTypes.CURSOR);
//执行调用存储过程
cstm.execute();
//获得执行后返回的游标集合,其索引对应着存储过程中的参数位置,如本题是对应着第二个,为CURSUR
ResultSet rs=(ResultSet)cstm.getObject(2);
while(rs.next()){
//获得游标中(也即emp表中的信息)
//取出第一个字段值 empno---number
intid=rs.getInt(1);
String ename=rs.getString(2);
System.out.println("员工编号:"+id+" 员工姓名:"+ename);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
db.closeConn(conn);
}
}
//获得CallableStatement,其为调用存储过程的对象
public static CallableStatement getCallableStatement(Connectionconn) throws SQLException{
//调用存储过程的语句{callpackage body name.procedureName(?..?)}
String sql="{callfirst_package.proc_cur(?,?)}";
//获得调用存储过程的对象
CallableStatementcstm=conn.prepareCall(sql);
return cstm;
}
}
第二种存储过程的使用方法:
1:新建一个Packages,例如名称为:first_package
create or replace packagefirst_package is
-- Public type declarations
type mycur is ref cursor;
procedure proc_cur(dno in number,cur out mycur);
end first_package;
2:直接创建procedure,而不用再实现package bodies
create or replace procedureproc_cur(dno innumber, mycur outfirst_package.mycur)
is
begin
open mycur for select * from emp where emp.deptno=dno;
end proc_cur;
3:Java中直接调用
//"{call 存储过程名(parameterp1,parameter p2,...)}"
//获取CallableStatement调用存储过程的对象
public static CallableStatementgetCallableStatement(Connection conn){
String sql="{call proc_cur(?,?)}";
CallableStatement cstm=null;
try {
cstm=conn.prepareCall(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return cstm;
}
其它代码和DBUtils和测试类JdbcTest一样