1.创建一个oracle存储过程 p_empInfo2 并执行,使这段sql代码能编译存储到oracle数据库中。
1 --输入员工号查询某个员工(7839)信息,将薪水作为返回值输出,给调用的程序使用 2 create or replace procedure p_empInfo2(i_empno IN emp.empno%TYPE, o_sal out emp.Sal%TYPE) as 3 4 begin 5 select sal into o_sal from emp where empno = i_empno; 6 7 end p_empInfo2;
2.使用jdbc调用该存储过程,环境工具:jdk1.8 intelliJ IDEA ,下载jar包 ojdbc6.jar 备用。
在IDEA中新建一个普通的java项目,建一个跟src目录平级的lib目录,把jar包拷贝进去,右键单击jar包,add as library ,如下:
然后新建一个 ProcedureTest类,调用存储过程
1 package com.lch.oracle; 2 3 import oracle.jdbc.OracleTypes; 4 5 import java.sql.CallableStatement; 6 import java.sql.Connection; 7 import java.sql.DriverManager; 8 9 /** 10 * Java使用jdbc调用存储过程示例 11 */ 12 public class ProcedureTest { 13 public static void main(String[] args) throws Exception { 14 //1.加载驱动包 15 Class.forName("oracle.jdbc.driver.OracleDriver"); 16 String url = "jdbc:oracle:thin:@localhost:1521:ORCL"; 17 String userName = "scott"; 18 String password = "tiger"; 19 //2.获得连接对象 20 Connection conn = DriverManager.getConnection(url, userName, password); 21 //3.设置补全sql参数 22 String sql = "{call p_empInfo2(?,?)}"; //调用存储过程的语句 23 CallableStatement call = conn.prepareCall(sql); 24 call.setInt(1, 7839); //设置输入参数 25 call.registerOutParameter(2, OracleTypes.DOUBLE);//设置输出参数 —— 必须在执行存储过程之前进行注册 26 //4 . 执行存储过程 (如果是普通的CRUD,这里是写发送sql语句的代码) 27 call.execute(); 28 //5.处理执行结果 29 double sal = call.getDouble(2); 30 System.out.println("员工薪水为:" + sal); 31 //6.释放资源 32 call.close(); 33 conn.close(); 34 } 35 }
3. 使用 Connection接口 创建CallableStatement 对象调用存储过程
Java API对 CallableStatement 接口的介绍:
public interface CallableStatement extends PreparedStatement 用于执行 SQL 存储过程的接口。JDBC API 提供了一个存储过程 SQL 转义语法,该语法允许对所有 RDBMS 使用标准方式调用存储过程。此转义语法有一个包含结果参数的形式和一个不包含结果参数的形式。如果使用结果参数,则必须将其注册为 OUT 型参数。其他参数 可用于输入、输出或同时用于二者。参数是根据编号按顺序引用的,第一个参数的编号是 1。
{?= call <procedure-name>[<arg1>,<arg2>, ...]}
{call <procedure-name>[<arg1>,<arg2>, ...]}
IN 参数值是使用从 PreparedStatement 中继承的 set 方法设置的。在执行存储过程之前, 必须注册所有 OUT 参数的类型;它们的值是在执行后通过此类提供的 get 方法检索的。
CallableStatement 可以返回一个 ResultSet 对象或多个 ResultSet 对象。多个 ResultSet 对象是使用从 Statement 中继承的操作处理的。为了获得最大的可移植性,某一调用的 ResultSet 对象和更新计数应该在获得输出参数的值之前处理。