【转】JDBC调用存储过程之实例讲解
2013-06-15 21:55
513 查看
JDBC调用存储过程之实例讲解
【说明】:本文主要讲解使用JDBC调用存储过程的各种方案,数据库使用Oracle(其他数据库类似)涉及到的数据表均为Oracle自带的Scott帐号的数据表。
【引言】:存储过程是数据库使用的重要技术之一,以其高效率、高安全性见长,而JDBC调用存储过程也是Java程序员必掌握的技能之一。JDBC调用存储过程主要使用CallableStatement接口,而对于输入(in)和输出(out)参数的处理也比较复杂,本文使用案例并有详细注解来说明各种情况。
一、调用带输入\输出参数的存储过程
1. 建立存储过程
2. JDBC的调用
3. 输出结果
二、调用带参数及返回值的函数
1. 建立函数
2. JDBC调用
3. 输出结果
三、调用输出参数为游标的存储过程
1. 创建存储过程
2. JDBC调用
3. 输出结果
四、 调用返回值为游标的函数
1. 创建函数
2. JDBC调用
3. 输出结果同上
五、 调用自声明游标类型的存储过程
1. 创建存储过程
2. JDBC调用:同上
3. 显示结果:同上
补充:如果调用不带任何参数的存储过程格式为{call 存储过程名}。
【说明】:本文主要讲解使用JDBC调用存储过程的各种方案,数据库使用Oracle(其他数据库类似)涉及到的数据表均为Oracle自带的Scott帐号的数据表。
【引言】:存储过程是数据库使用的重要技术之一,以其高效率、高安全性见长,而JDBC调用存储过程也是Java程序员必掌握的技能之一。JDBC调用存储过程主要使用CallableStatement接口,而对于输入(in)和输出(out)参数的处理也比较复杂,本文使用案例并有详细注解来说明各种情况。
一、调用带输入\输出参数的存储过程
1. 建立存储过程
-- 输入职工号(zgh)、输出姓名(xm)和工资(gz) create or replace procedure getNameSalByNo(zgh in emp.empno%type,xm out emp.ename%type,gz out emp.sal%type) is begin select ename,sal into xm,gz from emp where empno=zgh; end; |
package com.tjxz.proc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Types; public class CallProcedure { /** * 调用带普通参数的存储过程 * @author icer * @web http://www.tjxz.com */ public static void main(String[] args) { // 设置JDBC参数信息 String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String uid = "scott"; String pwd = "triger"; try { // 创建接受返回值的变量(姓名:xm,工资:gz) String xm=""; float gz=0.0f; /* * 准备SQL语句 |
* 格式为: {call 存储过程名{?,?,?}} * 括号中的问号和存储过程参数进行匹配 */ String sql = "{call getNameSalByNo(?,?,?)}"; // 加载驱动程序 Class.forName("oracle.jdbc.driver.OracleDriver"); // 获取连接对象 Connection con = DriverManager.getConnection(url, uid, pwd); // 获取执行对象 CallableStatement cst = con.prepareCall(sql); // 执行之前要使用setXXX来替换SQL语句中的问号参数 cst.setInt(1, 7788); // 注册输出参数类型(注意索引要和问号的位置对应) cst.registerOutParameter(2, Types.VARCHAR); cst.registerOutParameter(3, Types.FLOAT); // 执行SQL命令 cst.execute(); // 提取输出参数 xm = cst.getString(2); gz = cst.getFloat(3); // 控制台输出 System.out.println("姓名:" + xm); System.out.println("工资:" + gz); // 关闭相关对象 cst.close(); con.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } |
姓名:SCOTT 工资:3000.0 |
1. 建立函数
-- 输入职工号(zgh),输出工资(gz) create or replace function getSalByNo(zgh in emp.empno%type) return emp.sal%type is |
gz emp.sal%type; begin select sal into gz from emp where empno=zgh; return gz; exception when others then return -1; end; |
package com.tjxz.proc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Types; public class CallFunction { /** * 调用带参数及返回值的函数 * @author icer * @web http://www.tjxz.com */ public static void main(String[] args) { // 设置JDBC参数信息 String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String uid = "scott"; String pwd = "triger"; try { // 创建接受返回值的变量(工资:gz) float gz=0.0f; /* * 准备SQL语句 * 格式为: {?=call 函数名{?,?,?}} * 括号中的问号和函数参数进行匹配,使用?=接受返回值 */ String sql = "{?=call getSalByNo(?)}"; // 加载驱动程序 Class.forName("oracle.jdbc.driver.OracleDriver"); // 获取连接对象 Connection con = DriverManager.getConnection(url, uid, pwd); // 获取执行对象 CallableStatement cst = con.prepareCall(sql); |
// 执行之前要使用setXXX来替换SQL语句中的问号参数 cst.setInt(2, 7788); // 注册输出参数类型(注意索引要和问号的位置对应) cst.registerOutParameter(1, Types.FLOAT); // 执行SQL命令 cst.execute(); // 提取输出参数 gz = cst.getFloat(1); // 控制台输出 System.out.println("工资:" + gz); // 关闭相关对象 cst.close(); con.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } |
工资:3000.0 |
1. 创建存储过程
-- 输入部门编号(dno),输出此部门的所职工信息 /*说明:sys_refcursor为系统已定义的动态游标类型声明*/ create or replace procedure getEmpByDeptno(dno in emp.deptno%type,emps out sys_refcursor) is begin open emps for select * from emp where deptno=dno; end; |
package com.tjxz.proc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import oracle.jdbc.internal.OracleTypes; |
public class CallProcedureOfCursor { /** * 调用输出参数为游标的存储过程 * @author icer * @web http://www.tjxz.com */ public static void main(String[] args) { // 设置JDBC参数信息 String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String uid = "scott"; String pwd = "triger"; try { /* * 准备SQL语句 格式为: {call 存储过程名{?,?,?}} * 括号中的问号和存储过程参数进行匹配 */ String sql = "{call getEmpByDeptno(?,?)}"; // 加载驱动程序 Class.forName("oracle.jdbc.driver.OracleDriver"); // 获取连接对象 Connection con = DriverManager.getConnection(url, uid, pwd); // 获取执行对象 CallableStatement cst = con.prepareCall(sql); // 执行之前要使用setXXX来替换SQL语句中的问号参数 cst.setInt(1, 10); // 注册输出参数类型(注意索引要和问号的位置对应) cst.registerOutParameter(2, OracleTypes.CURSOR); // 执行SQL命令 cst.execute(); // 提取输出参数(输出游标使用ResultSet类型接收) ResultSet rst = (ResultSet) cst.getObject(2); // 控制台输出 System.out.println("EMPNO\tENAME"); System.out.println("----------------------"); while (rst.next()) { System.out.println(rst.getInt("empno") + "\t" + rst.getString("ename")); } // 关闭相关对象 rst.close(); cst.close(); con.close(); } catch (ClassNotFoundException e) { |
e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } |
EMPNO ENAME ---------------------- 7782 CLARK 7839 KING 7934 MILLER |
1. 创建函数
-- 输入部门编号(dno),返回此部门的所职工信息 /*说明:sys_refcursor为系统已定义的动态游标类型声明*/ create or replace function getEmpsByDeptno(dno in emp.deptno%type) return sys_refcursor is emps sys_refcursor; begin open emps for select * from emp where deptno=dno; return emps; end; |
package com.tjxz.proc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import oracle.jdbc.internal.OracleTypes; public class CallFunctionOfCursor { /** * 调用返回值为游标的函数 * * @author icer * @web http://www.tjxz.com */ |
public static void main(String[] args) { // 设置JDBC参数信息 String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String uid = "scott"; String pwd = "triger"; try { /* * 准备SQL语句,格式为: {?=call 函数名{?,?,?}} * 括号中的问号和函数参数进行匹配,使用?=接受返回值 */ String sql = "{?=call getEmpsByDeptno(?)}"; // 加载驱动程序 Class.forName("oracle.jdbc.driver.OracleDriver"); // 获取连接对象 Connection con = DriverManager.getConnection(url, uid, pwd); // 获取执行对象 CallableStatement cst = con.prepareCall(sql); // 执行之前要使用setXXX来替换SQL语句中的问号参数 cst.setInt(2, 10); // 注册输出参数类型(注意索引要和问号的位置对应) cst.registerOutParameter(1, OracleTypes.CURSOR); // 执行SQL命令 cst.execute(); // 提取输出参数(输出游标使用ResultSet类型接收) ResultSet rst = (ResultSet) cst.getObject(1); // 控制台输出 System.out.println("EMPNO\tENAME"); System.out.println("----------------------"); while (rst.next()) { System.out.println(rst.getInt("empno") + "\t" + rst.getString("ename")); } // 关闭相关对象 rst.close(); cst.close(); con.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } |
五、 调用自声明游标类型的存储过程
1. 创建存储过程
/*不使用系统已声明的动态游标类型,在程序包中自己声明动态游标类型*/ -- 创建程序包首部,声明游标和存储过程 create or replace package pk_scott as -- 声明动态游标类型 type dcur is ref cursor; -- 声明存储过程 procedure getEmpByDeptno(dno in emp.deptno%type,emps out dcur); end; -- 创建程序包体,并实现存储过程 create or replace package body pk_scott as -- 实现存储过程,输入部门号返回此部门所有雇员信息 procedure getEmpByDeptno(dno in emp.deptno%type,emps out dcur) is begin open emps for select * from emp where deptno=dno; end; end; |
3. 显示结果:同上
补充:如果调用不带任何参数的存储过程格式为{call 存储过程名}。
相关文章推荐
- JDBC基于MVC架构项目实例-实现对MySQL数据表的增删改查、调用数据表中的存储过程和函数
- JDBC调用存储过程实例
- 实例讲解JSP调用SQL Server的存储过程
- ADO调用存储过程实例讲解
- ADO调用分页查询存储过程的实例讲解
- JDBC调用存储过程实例
- MySQL 存储过程实例 与 ibatis/mybatis/hibernate/jdbc 如何调用存储过程
- java调用存储过程(jdbc & hibernate)
- 实例解析MySQL中的存储过程及存储过程的调用方法
- [转载] 存储过程从入门到熟练(多个存储过程完整实例及调用方
- 实例讲解如何把表格变量传递到存储过程中
- PHP调用MYSQL存储过程实例
- mysql存储过程详细讲解及完整实例下载
- 【Java EE 学习 29 下】【JDBC编程中操作Oracle数据库】【调用存储过程的方法】
- (转)jdbc 调用 sql server 的存储过程时“该语句没有返回结果集”的解决方法
- mybatis调用存储过程的实例代码
- SQL SERVER 2008存储过程生成编号,JDBC调用
- Spring Data JPA调用存储过程实例
- [MS SQL]存储过程实例讲解-侦错
- spring jdbctemplate或jdbc调用返回游标或复杂数据类型的存储过程