`
jslfl
  • 浏览: 312614 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

JDBC 调用返回多条记录的存储过程(转)

阅读更多
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import com.microsoft.jdbc.sqlserver.SQLServerDriver;


public class InvokeProcedure {

    private static Connection getConnection() {
        Connection conn = null;
        String url ="jdbc:oracle:thin:@127.0.0.1:1521:demo";
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            conn = DriverManager.getConnection(url, "scott", "tiger");
        } catch (Exception e) {
            System.out.println("");
            e.printStackTrace();
        }
        return conn;
       
    }
   
    private static Connection getsqlConnection() {
        Connection conn = null;
        String url ="jdbc:microsoft:sqlserver://localhost:1433;databaseName=y2";
        try {
            Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
            conn = DriverManager.getConnection(url, "sa", "");
        } catch (Exception e) {
            System.out.println("");
            e.printStackTrace();
        }
        return conn;
       
    }   
   
    //调用oracle的存储过程 --->  查询数据得到游标
    public static void  invokeProcedureResutl(){
        Connection conn =null;
        CallableStatement callableStatement =null;
        try {
            conn = getConnection();
            //第一步:获得CallableStatemen的实例;
            callableStatement = conn.prepareCall("{call p_result.pro_get_result(?,?,?,?)}");
           
            //第二步:为输出参数注册数据类型,为输入参数赋值;
            callableStatement.registerOutParameter(1,oracle.jdbc.driver.OracleTypes.CURSOR);
            callableStatement.setString(2, "emp");
            callableStatement.setInt(3, 2);
            callableStatement.setInt(4, 4);
            //第三步:执行存贮过程和获得返回值
            callableStatement.execute();
            ResultSet result =(ResultSet)callableStatement.getObject(1);
            if (result!=null){
                while(result.next()){
                     //result.get
                }
            }
            //System.out.println(result);
           
        } catch (Exception e) {
            e.printStackTrace();
        }   
       
    }
   

    public static void main(String[] args) {
       
        //InvokeProcedure.getConnection();
        InvokeProcedure.invokeProce();

    }
   
    //调用sqlserver的存储过程 ---  查询数据 select * from 表 where date > 2005.12.14
    public static void  invokeProce(){
        Connection conn =null;
        CallableStatement callableStatement =null;
        try {
            conn = getsqlConnection();
            //第一步:获得CallableStatemen的实例;
            callableStatement = conn.prepareCall("{call pop_pro(?)}");
           
            //第二步:为输出参数注册数据类型,为输入参数赋值;
            callableStatement.setString(1, "2005.12.14");
            //第三步:执行存贮过程和获得返回值
            callableStatement.execute();
            ResultSet result =callableStatement.getResultSet();
            if (result!=null){
                while(result.next()){
                     //result.get
                }
            }
            //System.out.println(result);
           
        } catch (Exception e) {
            e.printStackTrace();
        }   
    }
}

来自http://blog.csdn.net/binbin_520/article/details/2260166

CallableStatement   对象为所有的   DBMS   提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是   CallableStatement对象所含的内容。这种调用是用一种换码语法来写的,有两种形式:一种形式带结果参,另一种形式不带结果参数。结果参数是一种输出   (OUT)   参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN   参数)、输出(OUT   参数)或输入和输出(INOUT   参数)的参数。问号将用作参数的占位符。  
   
   在   JDBC   中调用已储存过程的语法如下所示。注意,方括号表示其间的内容是可选项;方括号本身并非语法的组成部份。  
  {call   过程名[(?,   ?,   ...)]}  
    返回结果参数的过程的语法为:  
  {?   =   call   过程名[(?,   ?,   ...)]}  
    不带参数的已储存过程的语法类似:  
  {call   过程名}  
    通常,创建   CallableStatement   对象的人应当知道所用的   DBMS   是支持已储存过程的,并且知道这些过程都是些什么。然而,如果需要检查,多种DatabaseMetaData   方法都可以提供这样的信息。例如,如果   DBMS   支持已储存过程的调用,则supportsStoredProcedures   方法将返回   true,而getProcedures   方法将返回对已储存过程的描述。CallableStatement   继承   Statement   的方法(它们用于处理一般的   SQL   语句),还继承了   PreparedStatement   的方法(它们用于处理   IN   参)。  
    CallableStatement   中定义的所有方法都用于处理   OUT   参数或   INOUT   参数的输出部分:注册   OUT   参数的   JDBC   类型(一般   SQL   类型)、从这些参数中检索结果,或者检查所返回的值是否为   JDBC   NULL。  
  1、创建   CallableStatement   对象  
    CallableStatement   对象是用   Connection   方法   prepareCall   创建的。下例创建   CallableStatement   的实例,其中含有对已储存过程   getTestData   调用。该过程有两个变量,但不含结果参数:  
  CallableStatement   cstmt   =   con.prepareCall("{call   getTestData(?,   ?)}");  
    其中?占位符为IN、OUT还是INOUT参数,取决于已储存过程getTestData。  
  2、IN和OUT参数  
    将IN参数传给   CallableStatement   对象是通过   setXXX   方法完成的。该方法继承自   PreparedStatement。所传入参数的类型决定了所用的setXXX方法(例如,用   setFloat   来传入   float   值等)。  
    如果已储存过程返回   OUT   参数,则在执行   CallableStatement   对象以前必须先注册每个   OUT   参数的   JDBC   类型(这是必需的,因为某些   DBMS   要求   JDBC   类型)。注册   JDBC   类型是用   registerOutParameter   方法来完成的。语句执行完后,CallableStatement   的   getXXX   方法将取回参数值。正确的   getXXX   方法是为各参数所注册的   JDBC   类型所对应的   Java   类型。换言之,   registerOutParameter   使用的是   JDBC   类型(因此它与数据库返回的   JDBC   类型匹配),而   getXXX   将之转换为   Java   类型。  
    作为示例,下述代码先注册   OUT   参数,执行由   cstmt   所调用的已储存过程,然后检索在   OUT   参数中返回的值。方法   getByte   从第一个   OUT   参数中取出一个   Java   字节,而   getBigDecimal   从第二个   OUT   参数中取出一个   BigDecimal   对象(小数点后面带三位数):  
  CallableStatement   cstmt   =   con.prepareCall("{call   getTestData(?,   ?)}");  
  cstmt.registerOutParameter(1,   java.sql.Types.TINYINT);  
  cstmt.registerOutParameter(2,   java.sql.Types.DECIMAL,   3);  
  cstmt.executeQuery();  
  byte   x   =   cstmt.getByte(1);  
  java.math.BigDecimal   n   =   cstmt.getBigDecimal(2,   3);  
   
    CallableStatement   与   ResultSet   不同,它不提供用增量方式检索大   OUT   值的特殊机制。  
   
  3、INOUT参数  
    既支持输入又接受输出的参数(INOUT   参数)除了调用   registerOutParameter   方法外,还要求调用适当的   setXXX   方法(该方法是从   PreparedStatement   继承来的)。setXXX   方法将参数值设置为输入参数,而   registerOutParameter   方法将它的   JDBC   类型注册为输出参数。setXXX   方法提供一个   Java   值,而驱动程序先把这个值转换为   JDBC   值,然后将它送到数据库中。这种   IN   值的   JDBC   类型和提供给   registerOutParameter   方法的   JDBC   类型应该相同。然后,要检索输出值,就要用对应的   getXXX   方法。例如,Java   类型为byte   的参数应该使用方法   setByte   来赋输入值。应该给registerOutParameter   提供类型为   TINYINT   的   JDBC   类型,同时应使用   getByte   来检索输出值。  
    下例假设有一个已储存过程   reviseTotal,其唯一参数是   INOUT   参数。方法setByte   把此参数设为   25,驱动程序将把它作为   JDBC   TINYINT   类型送到数据库中。接着,registerOutParameter   将该参数注册为   JDBC   TINYINT。执行完该已储存过程后,将返回一个新的   JDBC   TINYINT   值。方法   getByte   将把这个新值作为   Java   byte   类型检索。  
  CallableStatement   cstmt   =   con.prepareCall("{call   reviseTotal(?)}");  
  cstmt.setByte(1,   25);  
  cstmt.registerOutParameter(1,   java.sql.Types.TINYINT);  
  cstmt.executeUpdate();  
  byte   x   =   cstmt.getByte(1);  
   
  4、先检索结果,再检索   OUT   参数  
   
    由于某些   DBMS   的限制,为了实现最大的可移植性,建议先检索由执行CallableStatement   对象所产生的结果,然后再用   CallableStatement.getXXX   方法来检索   OUT   参数。如果   CallableStatement   对象返回多个   ResultSet   对象(通过调用   execute   方法),在检索   OUT   参数前应先检索所有的结果。这种情况下,为确保对所有的结果都进行了访问,必须对   Statement   方法   getResultSet、getUpdateCount   和getMoreResults   进行调用,直到不再有结果为止。  
   
    检索完所有的结果后,就可用   CallableStatement.getXXX   方法来检索   OUT   参数中的值。  
   
  5、检索作为OUT参数的NULL值  
   
  返回到   OUT   参数中的值可能会是JDBC   NULL。当出现这种情形时,将对   JDBC   NULL   值进行转换以使   getXXX   方法所返回的值为   null、0   或   false,这取决于getXXX   方法类型。对于   ResultSet   对象,要知道0或false是否源于JDBCNULL的唯一方法,是用方法wasNull进行检测。如果   getXXX   方法读取的最后一个值是   JDBC   NULL,则该方法返回   true,否则返回   flase。
分享到:
评论

相关推荐

    Spring Data JDBC与JDBC的区别

    JDBC规范   java.sql和javax.sql两个包中的类与接口(天龙八部):  DataSource:数据源 ... ResultSet:结果集,封装了多条记录  JDBC数据库连接池/Connection Pool  DBCP:apache tomcat内置  

    springmybatis

    MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例157 动态调用类中的方法 204 实例158 动态实例化类 205 实例159 创建长度可变的数组 206 实例160 利用反射重写toString()方法 208 实例161 反射与动态代理 209 7.3 常见的未检查型异常 210 实例162 算数异常 210...

    java面试800题

    如果调用EJB组件方法的客户端应用处于事务过程中,则调用组件商务方法时原有事务过程挂起,直至组件方法运行结束; 5.Supports:组件方法必须处于事务范围内。如果调用组件商务方法的客户端不处于事务过程中,则EJB...

    Java面试宝典2020修订版V1.0.1.doc

    19、用JDBC如何调用存储过程 69 20、JDBC中的PreparedStatement相比Statement的好处 71 21、写一个用jdbc连接实例。 71 22、ArrayList和Vector的区别? 73 23、List、Set和Map的区别? 74 24、Collection 和 ...

    超级有影响力霸气的Java面试题大全文档

    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 20、abstract class和interface有什么区别? ...

    Python Cookbook

    17.8 从Python可调用的C函数中返回None 611 17.9 用gdb调试动态载入的C扩展 613 17.10 调试内存问题 614 第18章 算法 616 引言 616 18.1 消除序列中的重复 619 18.2 在保留序列顺序的前提下消除其中的重复 ...

    java 面试题 总结

    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。 17、abstract class和interface有什么区别? 声明方法...

    03开源NewSql数据库TiDB-Deep Dive into TiDB

    Coprocessor 返回更多的统计信息,以便指导 TiDB 的行为 支持 ImportSST API,可以用于 SST 文件导入 [experimental] 新增 TiKV Importer 二进制,与 TiDB Lightning 集成用于快速导入数据 [experimental] 2.性能...

    疯狂JAVA讲义

    11.6.1 菜单条、菜单和菜单项 414 11.6.2 右键菜单 416 学生提问:为什么即使我没有给多行文本域编写右键菜单,但当我在多行文本域上单击右键时一样会弹出右键菜单? 418 11.7 在AWT中绘图 418 11.7.1 画图的...

    ibatis 开发指南(pdf)

    程序员甚至不需要对SQL 的熟练掌握, Hibernate/OJB 会根据制定的存储逻辑,自动生成对应的SQL 并调用JDBC 接口加以执 行。 大多数情况下( 特别是对新项目,新系统的开发而言) ,这样的机制无往不利...

    ssh(structs,spring,hibernate)框架中的上传下载

    文件数据存储在Blob类型的FILE_CONTENT表字段上,在Spring中采用OracleLobHandler来处理Lob字段(包括Clob和Blob),由于在程序中不需要引用到oracle数据驱动程序的具体类且屏蔽了不同数据库处理Lob字段方法上的差别...

    最新Java面试宝典pdf版

    22、用JDBC如何调用存储过程 109 23、JDBC中的PreparedStatement相比Statement的好处 110 24. 写一个用jdbc连接并访问oracle数据的程序代码 111 25、Class.forName的作用?为什么要用? 111 26、大数据量下的分页解决...

    Java面试宝典2010版

    22、用JDBC如何调用存储过程 23、JDBC中的PreparedStatement相比Statement的好处 24. 写一个用jdbc连接并访问oracle数据的程序代码 25、Class.forName的作用?为什么要用? 26、大数据量下的分页解决方法。 27、用...

    Java面试笔试资料大全

    22、用JDBC如何调用存储过程 109 23、JDBC中的PreparedStatement相比Statement的好处 110 24. 写一个用jdbc连接并访问oracle数据的程序代码 111 25、Class.forName的作用?为什么要用? 111 26、大数据量下的分页解决...

    PL/SQL 基础.doc

    5) JDBC 6) PL/SQL: 存储在数据库内运行, 其他方法为在数据库外对数据库访问,只适合ORACLE; 2. PL/SQL 1) PL/SQL(Procedual language/SQL)是在标准SQL的基础上增加了过程化处理的语言; 2) Oracle客户端工具...

Global site tag (gtag.js) - Google Analytics