• [1]、只有输入IN参数,没有输出OUT参数
  • [2]、既有输入IN参数,也有输出OUT参数,输出是简单值(非列表)
  • [3]、既有输入IN参数,也有输出OUT参数,输出是列表
  • [4]、输入输出参数是同一个(IN OUT)
  • create table TMP_MICHAEL
    (
    USER_ID VARCHAR2(20),
    USER_NAME VARCHAR2(10),
    SALARY NUMBER(8,2),
    OTHER_INFO VARCHAR2(100)
    ) insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)
    values ('michael', 'Michael', 5000, 'http://sjsky.iteye.com');
    insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)
    values ('zhangsan', '张三', 10000, null);
    insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)
    values ('aoi_sola', '苍井空', 99999.99, 'twitter account');
    insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)
    values ('李四', '李四', 2500, null);

    Oracle jdbc 常量:

  •     private final static String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
    private final static String DB_CONNECTION = "jdbc:oracle:thin:@127.0.0.1:1521:Ora11g";
    private final static String DB_NAME = "mytest";
    private final static String DB_PWd = "111111";

    [一]、只有输入IN参数,没有输出OUT参数

    存储过程 TEST_MICHAEL_NOOUT 的相关SQL:

  • CREATE OR REPLACE PROCEDURE TEST_MICHAEL_NOOUT(P_USERID    IN VARCHAR2,
    P_USERNAME IN VARCHAR2,
    P_SALARY IN NUMBER,
    P_OTHERINFO IN VARCHAR2) IS
    BEGIN INSERT INTO TMP_MICHAEL
    (USER_ID, USER_NAME, SALARY, OTHER_INFO)
    VALUES
    (P_USERID, P_USERNAME, P_SALARY, P_OTHERINFO); END TEST_MICHAEL_NOOUT;

    调用代码如下:

  •  /**
    * 测试调用存储过程:无返回值
    * @blog http://sjsky.iteye.com
    * @author Michael
    * @throws Exception
    */
    public static void testProcNoOut() throws Exception {
    System.out.println("------- start 测试调用存储过程:无返回值");
    Connection conn = null;
    CallableStatement callStmt = null;
    try {
    Class.forName(DB_DRIVER);
    conn = DriverManager.getConnection(DB_CONNECTION, DB_NAME, DB_PWd);
    // 存储过程 TEST_MICHAEL_NOOUT 其实是向数据库插入一条数据
    callStmt = conn.prepareCall("{call TEST_MICHAEL_NOOUT(?,?,?,?)}"); // 参数index从1开始,依次 1,2,3...
    callStmt.setString(1, "jdbc");
    callStmt.setString(2, "JDBC");
    callStmt.setDouble(3, 8000.00);
    callStmt.setString(4, "http://sjsky.iteye.com");
    callStmt.execute();
    System.out.println("------- Test End.");
    } catch (Exception e) {
    e.printStackTrace(System.out);
    } finally {
    if (null != callStmt) {
    callStmt.close();
    }
    if (null != conn) {
    conn.close();
    }
    }
    }

    [二]、既有输入IN参数,也有输出OUT参数,输出是简单值(非列表)

    存储过程 TEST_MICHAEL 的SQL如下:

  • CREATE OR REPLACE PROCEDURE TEST_MICHAEL(P_USERID IN VARCHAR2,
    P_SALARY IN NUMBER,
    P_COUNT OUT NUMBER) IS
    V_SALARY NUMBER := P_SALARY;
    BEGIN
    IF V_SALARY IS NULL THEN
    V_SALARY := 0;
    END IF;
    IF P_USERID IS NULL THEN
    SELECT COUNT(*)
    INTO P_COUNT
    FROM TMP_MICHAEL T
    WHERE T.SALARY >= V_SALARY;
    ELSE
    SELECT COUNT(*)
    INTO P_COUNT
    FROM TMP_MICHAEL T
    WHERE T.SALARY >= V_SALARY
    AND T.USER_ID LIKE '%' || P_USERID || '%';
    END IF;
    DBMS_OUTPUT.PUT_LINE('v_count=:' || P_COUNT);
    END TEST_MICHAEL;

    调用程序如下:

  •  /**
    * 测试调用存储过程:返回值是简单值非列表
    * @blog http://sjsky.iteye.com
    * @author Michael
    * @throws Exception
    */
    public static void testProcOutSimple() throws Exception {
    System.out.println("------- start 测试调用存储过程:返回值是简单值非列表");
    Connection conn = null;
    CallableStatement stmt = null;
    try {
    Class.forName(DB_DRIVER);
    conn = DriverManager.getConnection(DB_CONNECTION, DB_NAME, DB_PWd); stmt = conn.prepareCall("{call TEST_MICHAEL(?,?,?)}"); stmt.setString(1, "");
    stmt.setDouble(2, 3000); // out 注册的index 和取值时要对应
    stmt.registerOutParameter(3, Types.INTEGER);
    stmt.execute(); // getXxx(index)中的index 需要和上面registerOutParameter的index对应
    int i = stmt.getInt(3);
    System.out.println("符号条件的查询结果 count := " + i);
    System.out.println("------- Test End.");
    } catch (Exception e) {
    e.printStackTrace(System.out);
    } finally {
    if (null != stmt) {
    stmt.close();
    }
    if (null != conn) {
    conn.close();
    }
    }
    }

    测试程序就是查询薪水3000以上人员的数量 ,运行结果如下:

    ------- start 测试调用存储过程:返回值是简单值非列表 
    符号条件的查询结果 count := 4 
    ------- Test End.

    [三]、既有输入IN参数,也有输出OUT参数,输出是列表

    首先需要创建PACKAGE TEST_PKG_CURSOR 的SQL如下:

  • CREATE OR REPLACE PACKAGE TEST_PKG_CURSOR IS
    
      -- Author  : MICHAEL  http://sjsky.iteye.com
    TYPE TEST_CURSOR IS REF CURSOR; END TEST_PKG_CURSOR;

    再创建存储过程 TEST_P_OUTRS 的SQL如下:

  • CREATE OR REPLACE PROCEDURE TEST_P_OUTRS(P_SALARY IN NUMBER,
    P_OUTRS OUT TEST_PKG_CURSOR.TEST_CURSOR) IS
    V_SALARY NUMBER := P_SALARY;
    BEGIN
    IF P_SALARY IS NULL THEN
    V_SALARY := 0;
    END IF;
    OPEN P_OUTRS FOR
    SELECT * FROM TMP_MICHAEL T WHERE T.SALARY > V_SALARY;
    END TEST_P_OUTRS;

    调用存储过程的代码如下:

  •  /**
    * 测试调用存储过程:有返回值且返回值为列表的
    * @blog http://sjsky.iteye.com
    * @author Michael
    * @throws Exception
    */
    public static void testProcOutRs() throws Exception {
    System.out.println("------- start 测试调用存储过程:有返回值且返回值为列表的");
    Connection conn = null;
    CallableStatement stmt = null;
    ResultSet rs = null;
    try {
    Class.forName(DB_DRIVER);
    conn = DriverManager.getConnection(DB_CONNECTION, DB_NAME, DB_PWd); stmt = conn.prepareCall("{call TEST_P_OUTRS(?,?)}"); stmt.setDouble(1, 3000);
    stmt.registerOutParameter(2, OracleTypes.CURSOR);
    stmt.execute(); // getXxx(index)中的index 需要和上面registerOutParameter的index对应
    rs = (ResultSet) stmt.getObject(2);
    // 获取列名及类型
    int colunmCount = rs.getMetaData().getColumnCount();
    String[] colNameArr = new String[colunmCount];
    String[] colTypeArr = new String[colunmCount];
    for (int i = 0; i < colunmCount; i++) {
    colNameArr[i] = rs.getMetaData().getColumnName(i + 1);
    colTypeArr[i] = rs.getMetaData().getColumnTypeName(i + 1);
    System.out.print(colNameArr[i] + "(" + colTypeArr[i] + ")"
    + " | ");
    }
    System.out.println();
    while (rs.next()) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < colunmCount; i++) {
    sb.append(rs.getString(i + 1) + " | ");
    }
    System.out.println(sb);
    }
    System.out.println("------- Test Proc Out is ResultSet end. "); } catch (Exception e) {
    e.printStackTrace(System.out);
    } finally {
    if (null != rs) {
    rs.close();
    }
    if (null != stmt) {
    stmt.close();
    }
    if (null != conn) {
    conn.close();
    }
    }
    }

    运行结果如下:

    ------- start 测试调用存储过程:有返回值且返回值为列表的 
    USER_ID(VARCHAR2) | USER_NAME(VARCHAR2) | SALARY(NUMBER) | OTHER_INFO(VARCHAR2) |  
    michael | Michael | 5000 | null |  
    zhangsan | 张三 | 10000 | null |  
    aoi_sola | 苍井空 | 99999.99 | null |  
    jdbc | JDBC | 8000 | http://sjsky.iteye.com |  
    ------- Test Proc Out is ResultSet end.

    [四]、输入输出参数是同一个(IN OUT)

    创建存储过程TEST_P_INOUT 的SQL如下:

  • CREATE OR REPLACE PROCEDURE TEST_P_INOUT(P_USERID IN VARCHAR2,
    P_NUM IN OUT NUMBER) IS
    V_COUNT NUMBER;
    V_SALARY NUMBER := P_NUM;
    BEGIN
    IF V_SALARY IS NULL THEN
    V_SALARY := 0;
    END IF; SELECT COUNT(*)
    INTO V_COUNT
    FROM TMP_MICHAEL
    WHERE USER_ID LIKE '%' || P_USERID || '%'
    AND SALARY >= V_SALARY;
    P_NUM := V_COUNT;
    END TEST_P_INOUT;

    调用存储过程的代码:

  • /**
    * 测试调用存储过程: INOUT同一个参数:
    * @blog http://sjsky.iteye.com
    * @author Michael
    * @throws Exception
    */
    public static void testProcInOut() throws Exception {
    System.out.println("------- start 测试调用存储过程:INOUT同一个参数");
    Connection conn = null;
    CallableStatement stmt = null;
    try {
    Class.forName(DB_DRIVER);
    conn = DriverManager.getConnection(DB_CONNECTION, DB_NAME, DB_PWd); stmt = conn.prepareCall("{call TEST_P_INOUT(?,?)}"); stmt.setString(1, "michael");
    stmt.setDouble(2, 3000); // 注意此次注册out 的index 和上面的in 参数index 相同
    stmt.registerOutParameter(2, Types.INTEGER);
    stmt.execute(); // getXxx(index)中的index 需要和上面registerOutParameter的index对应
    int count = stmt.getInt(2);
    System.out.println("符号条件的查询结果 count := " + count);
    System.out.println("------- Test End.");
    } catch (Exception e) {
    e.printStackTrace(System.out);
    } finally {
    if (null != stmt) {
    stmt.close();
    }
    if (null != conn) {
    conn.close();
    }
    }
    }

    运行结果如下:

    ------- start 测试调用存储过程:INOUT同一个参数 
    符号条件的查询结果 count := 1 
    ------- Test End.

【参考】JDBC执行存储过程的四种情况的更多相关文章

  1. JDBC执行存储过程的四种情况 (转)

    本文主要是总结 如何实现 JDBC调用Oracle的存储过程,从以下情况分别介绍: [1].只有输入IN参数,没有输出OUT参数 [2].既有输入IN参数,也有输出OUT参数,输出是简单值(非列表) ...

  2. 存储过程:SET Transaction Isolation Level Read语法的四种情况

    这几天一直在弄存储过程,现在在这里跟大伙共享下资料: SET Transaction Isolation Level Read UNCOMMITTED 使用这句东东呢可以分为四种情况,现在就在这里逐一 ...

  3. SET Transaction Isolation Level Read语法的四种情况

    转自:http://www.cnblogs.com/qanholas/archive/2012/01/04/2312152.html 存储过程:SET Transaction Isolation Le ...

  4. Jdbc执行存储过程报数据库事务无法执行的异常

    Jdbc执行存储过程报数据库事务无法执行的异常 环境: Eclipse+Jdk1.7+spring-jdbc-3.0.7+同版本的jdbctemplate+Sqlserver 2012 问题: 一个小 ...

  5. Spring如何使用JdbcTemplate调用存储过程的三种情况

    注:原文 <Spring如何使用JdbcTemplate调用存储过程的三种情况 > Spring的SimpleJdbcTemplate将存储过程的调用进行了良好的封装,下面列出使用Jdbc ...

  6. JS生成某个范围的随机数(四种情况)

    前言: JS没有现成的函数,能够直接生成指定范围的随机数. 但是它有个函数:Math.random()  这个函数可以生成 [0,1) 的一个随机数. 利用它,我们就可以生成指定范围内的随机数. 而涉 ...

  7. JS生成某个范围的随机数【四种情况详解】

    JS没有现成的函数,能够直接生成指定范围的随机数. 但是它有个函数:Math.random()  这个函数可以生成 [0,1) 的一个随机数. 利用它,我们就可以生成指定范围内的随机数. 而涉及范围的 ...

  8. 从零开始学习前端JAVASCRIPT — JavaScript中this指向的四种情况

    JavaScript中this的四种情况(非严格模式) 1.当this所在函数是事件处理函数时,this指向事件源.2.当this所在函数是构造函数时,this指向new出来的对象.3.this所在函 ...

  9. 对存在JavaScript隐式类型转换的四种情况的总结

    一般存在四种情况,JavaScript会对变量的数据类型进行转换. 目录 * if中的条件会被自动转为Boolean类型 * 会被转为false的数据 * 会被转为true的数据 * 参与+运算都会被 ...

随机推荐

  1. pyspider architecture--官方文档

    原文地址:http://docs.pyspider.org/en/latest/Architecture/ Architecture This document describes the reaso ...

  2. WCF(一)控制台寄宿

    WCF是微软开发的一款通信框架.具有跨平台跨操作系统的特点,所以,WCF一般用于开发第三方接口或者在分布式系统用做数据交互. WCF三要素分别是地址(Address).绑定(Binding).契约(C ...

  3. php方法-------将汉字转为拼音或者提取汉字首字母

    将汉字转为全拼,提取汉字首字母 <?php /** * 基于PHP语言的汉语转拼音的类 * 兼容 UTF8.GBK.GB2312 编码,无须特殊处理 * 对中文默认返回拼音首字母缩写,其它字符不 ...

  4. CADisplayLink & NSTimer

    屏幕刷新与UI更新不同步:屏幕刷新由硬件(+GPU)保证,UI更新由软件(CPU保证). 出现卡顿的原因是软件的计算速度跟不上硬件的刷新速度. 一 简介 1 所在框架 CADisplayLink和其它 ...

  5. ABBYY FineReader双十一优惠享不停,战绩如何?

    随着双十一的火热来袭,购物达人也是不吝啬囊中票子,各种姿势剁手齐全,立誓过后吃土半月,双十一的好与不好?自己也是门清,反正真真的是促进消费了! 就ABBYYFineReader而言,此次的双十一力度就 ...

  6. 开源Android容器化框架Atlas开发者指南

    Atlas是古希腊神话中的天神,是波士顿动力公司的机器人,借助搜索引擎,得以发现这个名词背后许许多多的含义.在手机淘宝,Atlas是一个扎根于Android客户端的一个组件化容器框架,相比神话中用手和 ...

  7. hdu1542 矩形面积并(线段树+离散化+扫描线)

    题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...

  8. 2017CCPC秦皇岛

    热身赛 B题 Smartphone: 大整数相乘 Time Limit: 1 Second Memory Limit: 65536 KBHelianthuswolf Co. Ltd. is a mul ...

  9. 利用请求的JSON数据创建图形图层

    先看效果图: 包含三个部分:信息窗口(标题是要素的某个属性信息,其余是感兴趣的属性信息).图上图形按照某一属性大小不一显示,图例 1.创建底图用于存放以上三部分: "esri/Map&quo ...

  10. B-Tree概念

    记录下学习B-Tree: concept:(m-阶) 1.  根节点 孩子数 ( 2 <= N <= m) 根节点key数([m/2] - 1 <= n <=  m -1) 2 ...