需要用到的接口

接口 CallableStatement

JDK文档对改接口的说明:

  1. public interface CallableStatement
  2. extends
  3. PreparedStatement

用于执行 SQL 存储过程的接口。JDBC API 提供了一个存储过程 SQL 转义语法,该语法允许对所有 RDBMS 使用标准方式调用存储过程。此转义语法有一个包含结果参数的形式和一个不包含结果参数的形式。如果使用结果参数,则必须将其注册为 OUT 参数。其他参数可用于输入、输出或同时用于二者。参数是根据编号按顺序引用的,第一个参数的编号是 1。

  1. {?= call <procedure-name>[(<arg1>,<arg2>, ...)]} -------存储函数的sql,第一个?代表返回类型
  2. {call <procedure-name>[(<arg1>,<arg2>, ...)]} -------存储过程的sql

IN 参数值是使用继承自 PreparedStatement 的 set 方法设置的。在执行存储过程之前,必须注册所有 OUT 参数的类型;它们的值是在执行后通过此类提供的 get 方法获取的。

CallableStatement 可以返回一个 ResultSet 对象或多个 ResultSet 对象。多个 ResultSet 对象是使用继承自 Statement 的操作处理的。

为了获得最大的可移植性,某一调用的 ResultSet 对象和更新计数应该在获得输出参数的值之前处理。

例子程序

对oracle的scott/tiger用户的emp表操作

存储过程,查询员工信息

  1. create or replace procedure queryEmpInfo(eno in number,
  2. pename out varchar2,
  3. psal out number,
  4. pjob out varchar2)
  5. as
  6. begin
  7. select ename,sal,job into pename,psal,pjob from emp where empno=eno;
  8. end;

存储函数:

  1. create or replace function queryEmpImcome(eno in number)
  2. return number
  3. as
  4.  
  5. --变量
  6. psal emp.sal%type;
  7. pcomm emp.comm%type;
  8. begin
  9. select sal,comm into psal,pcomm from emp where empno=eno;
  10. return (psal+nvl(pcomm,0))*12;
  11.  
  12. end;

jdbc工具类

  1. package com.lhy.util;
  2. import java.sql.*;
  3.  
  4. /**
  5. * JDBC工具类 ,一般工具类final。
  6. * 工具类一般不需要new,不需要构造实例。(把构造方法私有)别人就new不了了。
  7. * 此时使用类的方法:
  8. * 1是单例模式(复杂点)
  9. * 2是提供静态的public方法。(简单)
  10. * 本例子是简单的提供public方法实现的。需要静态方法
  11. *
  12. * @author hy
  13. *
  14. */
  15. public final class JdbcUtils {
  16. private static String url ="jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
  17. private static String user ="scott";
  18. private static String passWord = "tiger";
  19.  
  20. //构造方法私有,别人不能构造,不会有实例出来.
  21. private JdbcUtils(){
  22.  
  23. }
  24.  
  25. /**
  26. * 静态代码块,类加载到虚拟机是只执行一次。
  27. */
  28. static {
  29. try {
  30. Class.forName("oracle.jdbc.driver.OracleDriver");
  31. } catch (ClassNotFoundException e) {
  32.  
  33. e.printStackTrace();
  34. }
  35.  
  36. }
  37.  
  38. public static Connection getConnection() {
  39. Connection conn = null;
  40. try {
  41. conn = DriverManager.getConnection(url,user,passWord);
  42. } catch (SQLException e) {
  43.  
  44. e.printStackTrace();
  45. }
  46. return conn;
  47.  
  48. }
  49.  
  50. //释放资源,重载方法。
  51. public static void close(Connection conn) {
  52. try {
  53. if(conn != null){
  54. conn.close();
  55. conn = null;
  56. }
  57. }catch(SQLException e){
  58. e.printStackTrace();
  59. }
  60. }
  61. public static void close(Statement stmt){
  62. try{
  63. if(stmt != null){
  64. stmt.close();
  65. stmt = null;
  66. }
  67. }catch(SQLException e){
  68. e.printStackTrace();
  69. }
  70. }
  71. public static void close(ResultSet rs){
  72. try{
  73. if(rs != null){
  74. rs.close();
  75. rs = null;
  76. }
  77. }catch (SQLException e) {
  78. e.printStackTrace();
  79. }
  80. }
  81. }

测试程序:

  1. public class OracleTest {
  2.  
  3. /**
  4. * 测试存储过程
  5. * create or replace procedure queryEmpInfo(eno in number,
  6. pename out varchar2,
  7. psal out number,
  8. pjob out varchar2)
  9. as
  10.  
  11. begin
  12. select ename,sal,job into pename,psal,pjob from emp where empno=eno;
  13. end;
  14. */
  15. @Test
  16. public void testProcedure(){
  17. //格式 {call <procedure-name>[(<arg1>,<arg2>, ...)]}
  18. String sql = "{call queryEmpInfo(?,?,?,?)}";
  19. Connection conn = null;
  20. CallableStatement call = null;
  21.  
  22. try {
  23. conn = JdbcUtils.getConnection();
  24. call = conn.prepareCall(sql);
  25. //赋值
  26. call.setInt(1, 7839);
  27. //对于out参数,声明
  28. call.registerOutParameter(2, OracleTypes.VARCHAR);
  29. call.registerOutParameter(3, OracleTypes.NUMBER);
  30. call.registerOutParameter(4, OracleTypes.VARCHAR);
  31.  
  32. //调用
  33. call.execute();
  34.  
  35. //取值
  36. String name = call.getString(2);
  37. double sal = call.getDouble(3);
  38. String job = call.getString(4);
  39. System.err.println(name);
  40. System.err.println(sal);
  41. System.err.println(job);
  42. }catch(Exception e){
  43. e.printStackTrace();
  44. }finally{
  45. JdbcUtils.close(call);
  46. JdbcUtils.close(conn);
  47. }
  48. }
  49.  
  50. /**
  51. * 测试 存储函数
  52. * create or replace function queryEmpImcome(eno in number)
  53. return number
  54. as
  55.  
  56. --变量
  57. psal emp.sal%type;
  58. pcomm emp.comm%type;
  59. begin
  60. select sal,comm into psal,pcomm from emp where empno=eno;
  61. return (psal+nvl(pcomm,0))*12;
  62.  
  63. end;
  64. */
  65. @Test
  66. public void testFunction(){
  67. //{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
  68. //第一个?--> 输出参数,返回值, 第二个 ?-->输入参数
  69. String sql = "{?= call queryEmpImcome(?)}";
  70. Connection conn = null;
  71. CallableStatement call = null;
  72.  
  73. try {
  74. conn = JdbcUtils.getConnection();
  75. call = conn.prepareCall(sql);
  76.  
  77. //注册输出参数
  78. call.registerOutParameter(1, OracleTypes.NUMBER);
  79. //输入参数
  80. call.setInt(2, 7839);
  81.  
  82. //执行
  83. call.execute();
  84. //取出年收入,注意是get 1
  85. double income = call.getDouble(1);
  86. System.err.println("年收入:"+income);
  87.  
  88. } catch (Exception e) {
  89. e.printStackTrace();
  90. }finally{
  91. JdbcUtils.close(call);
  92. JdbcUtils.close(conn);
  93. }
  94. }
  95. }

运行结果:

性能
Statement < preparedStatement < CallableStatement

在Out参数中使用游标

package:程序包

上边的例子的存储过程,输出参数只有三个,如果输出参数有很多,或者输出结果是一个结果集(如查询一个部门中所有员工的信息),此时就需要在out参数中使用游标

例子:查询某个部门所有员工的所有信息

使用PLSQL建包

1,新建包

  1. create or replace package MYPACKAGE as
  2.  
  3. type empcursor is ref cursor;
  4.  
  5. procedure queryEmpList(dno in number,empList out empcursor);
  6.  
  7. end MYPACKAGE;

2,新建包体

  1. CREATE OR REPLACE PACKAGE BODY MYPACKAGE AS
  2.  
  3. procedure queryEmpList(dno in number,empList out empcursor) AS
  4. BEGIN
  5.  
  6. open empList for select * from emp where deptno=dno;
  7.  
  8. END queryEmpList;
  9.  
  10. END MYPACKAGE;

使用java程序测试:

  1. @Test
  2. public void testCursor(){
  3. String sql = "{call MYPACKAGE.queryEmpList(?,?)}";
  4. Connection conn = null;
  5. CallableStatement call = null;
  6. ResultSet rs = null;
  7. try {
  8. conn = JdbcUtils.getConnection();
  9. call = conn.prepareCall(sql);
  10.  
  11. call.setInt(1, 10);
  12. call.registerOutParameter(2, OracleTypes.CURSOR);
  13.  
  14. //执行
  15. call.execute();
  16. //取出集合,转换为OracleCallableStatement,去除游标
  17. rs = ((OracleCallableStatement)call).getCursor(2);
  18. while(rs.next()){
  19. String name = rs.getString("ename");
  20. String job = rs.getString("job");
  21. double salary = rs.getDouble("sal");
  22.  
  23. System.err.println("姓名:"+name+",职位:"+job+",薪水:"+salary);
  24.  
  25. }
  26.  
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. }finally{
  30. JdbcUtils.close(rs);
  31. JdbcUtils.close(call);
  32. JdbcUtils.close(conn);
  33. }
  34. }

光标当ResultSet关闭的时候就关闭了

  1.  

java调用存储过程、存储函数的更多相关文章

  1. Java 调用存储过程、函数

     一.Java调用存储Oracle存储过程 测试用表: --创建用户表 create table USERINFO ( username ) not null, password ) not null ...

  2. java调用存储过程和函数

    以对表test进行增,删,改,查进行说明:1.新建表test create table TEST ( TID NUMBER not null, TNAME VARCHAR2(32), TCODE VA ...

  3. 【转】java调用存储过程和函数

    一.概述 如果想要执行存储过程,我们应该使用 CallableStatement 接口. CallableStatement 接口继承自PreparedStatement 接口.所以CallableS ...

  4. JDBC第二篇--【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】

    这是我JDBC的第一篇 http://blog.csdn.net/hon_3y/article/details/53535798 1.PreparedStatement对象 PreparedState ...

  5. JDBC【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】

    1.PreparedStatement对象 PreparedStatement对象继承Statement对象,它比Statement对象更强大,使用起来更简单 Statement对象编译SQL语句时, ...

  6. Oracle数据库游标,序列,存储过程,存储函数,触发器

    游标的概念:     游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理, ...

  7. Oracle学习(十二):存储过程/存储函数

    1.知识点 --第一个存储过程 /* 打印Hello World create [or replace] PROCEDURE 过程名(參数列表) AS PLSQL子程序体: 调用存储过程: 1. ex ...

  8. JDBC(13)—JDBC调用存储过程和函数

    步骤: JDBC调用存储过程和函数 步骤: ①:通过Connection对象的prepareCall()方法创建一个CallableStatement对象的实例,在使用Connection对象的pre ...

  9. Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器

    ---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...

  10. oracle 存储过程,存储函数,包,

    http://heisetoufa.iteye.com/blog/366957 认识存储过程和函数 存储过程和函数也是一种PL/SQL块,是存入数据库的PL/SQL块.但存储过程和函数不同于已经介绍过 ...

随机推荐

  1. Ubuntu 16.04安装MySQL及遇到的问题解决方案

    使用以下命令即可进行MySQL安装: sudo apt-get install mysql-server 上述命令会安装以下包: apparmor mysql-client-5.7 mysql-com ...

  2. 休息,考完了MCSD

    终于考完了~这次的证书签名居然还是鲍尔默的.

  3. (线段树 区间查询)The Water Problem -- hdu -- 5443 (2015 ACM/ICPC Asia Regional Changchun Online)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=5443 The Water Problem Time Limit: 1500/1000 MS (Java/ ...

  4. (线段树 点更新 区间求和)lightoj1112

    链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#problem/D (密码0817) Description Robin ...

  5. Codeforces805B. 3-palindrome 2017-05-05 08:33 156人阅读 评论(0) 收藏

    B. 3-palindrome time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  6. 四则运算(Java)--温铭淇,付夏阳

    GitHub项目地址: https://github.com/fxyJAVA/Calculation 四则运算项目要求: 程序处理用户需求的模式为: Myapp.exe -n num -r size ...

  7. Java子父类中的构造函数实例化过程

    其实我们发现子类继承父类操作很简单,如果要是去深入的研究下会发现,实例化过程并非是我们看到的那样,我们就以代码举例来说明: 问大家,以下代码执行会输出什么呢? package com.oop; /** ...

  8. 【Kindeditor编辑器】 文件上传、空间管理

    包括图片上传.文件上传.Flash上传.多媒体上传.空间管理(图片空间.文件空间等等) 一.编辑器相关参数 二.简单的封装类 这里只是做了简单的封装,欢迎大家指点改正. public class Ki ...

  9. vs2017新建.netcore相关项目提示"未检测到任何.NET Core SDK"或打开.net core 相关项目Web层总是未能正常加载

    近来vs2017出现一个非常怪的现象,之前新建.net core相关项目好好的,现在出现问题,如下: 解决办法,是更新vs2017,界面如下:

  10. 构建NetCore应用框架之实战篇(七):BitAdminCore框架登录功能源码解读

    本篇承接上篇内容,如果你不小心点击进来,建议从第一篇开始完整阅读,文章内容继承性连贯性. 构建NetCore应用框架之实战篇系列 一.简介 1.登录功能完成后,框架的雏形已经形成,有必要进行复习. 2 ...