`
Luob.
  • 浏览: 1592184 次
  • 来自: 上海
社区版块
存档分类
最新评论

Oracle 存储过程的使用

阅读更多
本文主要是总结 如何实现 JDBC调用Oracle的存储过程,从以下情况分别介绍:
[1]、只有输入IN参数,没有输出OUT参数
[2]、既有输入IN参数,也有输出OUT参数,输出是简单值(非列表)
[3]、既有输入IN参数,也有输出OUT参数,输出是列表
[4]、输入输出参数是同一个(IN OUT)
[5]、存储过程中 使用 truncate 截断表中的数据
【准备工作】
  创建一个测试表TMP_MICHAEL ,并插入数据,SQL如下:
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参数
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参数,输出是简单值(非列表)
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如下:
首先需要创建PACKAGE TEST_PKG_CURSOR 的SQL如下:
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如下:
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)
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.


[五] 存储过程中使用 truncate  清空表中的数据
create or replace procedure PROC_INSERT_BLDAREN(rownums in number) is
begin
  EXECUTE IMMEDIATE 'TRUNCATE TABLE BI_BAOLIAO_DAREN';
  insert into BI_BAOLIAO_DAREN (ID,USERID,USERNAME,BAOLIAONUM,CREDITS) select bi_baoliao_sequence.nextval,bl.* from (select b.userid,b.username,count(b.id),sum(b.credits) credits from bi_baoliao b  group by b.userid,b.username order by credits desc) bl where rownum <=rownums;
end PROC_INSERT_BLDAREN;

java 调用
/**
* 使用 truncate 先清空表中的数据
* 然后 插入数据
*/
public static boolean updateData1(int rownum){
		boolean result=true;
		Connection conn=null;
		CallableStatement  cs=null;
		try {
			Date stime=new Date();
			conn=DBConnection.getConnection();
			cs=conn.prepareCall("{call PROC_INSERT_BLDAREN(?)}");
			cs.setInt(1, rownum);
			result=cs.execute();
			Date etime=new Date();
			System.out.println(etime.getTime()-stime.getTime());
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			DBConnection.cleanUp(null, null, cs, null);
		}
		return result;
	}

分享到:
评论

相关推荐

    Oracle存储过程中使用临时表

    本篇文章将深入探讨如何在Oracle存储过程中使用临时表,包括会话级临时表和事务级临时表。 ### 会话级临时表 会话级临时表(Session-Level Temporary Tables)只在创建它的会话内可见,并且在会话结束时自动删除。...

    oracle存储过程使用游标对多表操作例子

    标题:“oracle存储过程使用游标对多表操作例子”直接指出了文章的主题是关于在Oracle环境下,如何利用存储过程和游标实现跨多个表的数据处理。描述部分重复了标题内容,强调了示例性质,表明文章将通过具体实例来...

    oracle存储过程学习经典入门

    用 Java 调用 Oracle 存储过程时,需要使用 JDBC 驱动程序来连接 Oracle 数据库,然后使用 CallableStatement 对象来调用存储过程。 在存储过程中做简单动态查询 在存储过程中,做简单动态查询需要使用 EXECUTE ...

    oracle存储过程使用详解

    ### Oracle存储过程使用详解 在Oracle数据库环境中,存储过程是一种重要的数据库对象,它允许开发者将一组SQL语句和控制流程语句封装在一个命名单元中,从而实现更复杂、更高效的数据处理逻辑。本文将深入探讨...

    超详细Oracle存储过程使用手册,只收1分

    这个“超详细Oracle存储过程使用手册”旨在为用户提供全面、深入的理解和实践指导。 一、存储过程的基础概念 存储过程是由一个或多个SQL和PL/SQL语句组成的程序单元,存储在数据库中并可以被调用执行。它们提高了...

    C#调用oracle方法(包括调用存储过程)

    本文将详细介绍如何使用C#语言连接Oracle数据库,并演示如何调用Oracle存储过程,特别是带有输出参数的情况。这些知识点对于初学者来说尤为重要。 #### 前置知识 1. **C#基础**:理解C#的基本语法和概念。 2. **...

    oracle 存储过程导出excel

    oracle 存储过程导出excel oracle 存储过程导出excel oracle 存储过程导出excel oracle 存储过程导出excel oracle 存储过程导出excel

    Python使用cx_Oracle调用Oracle存储过程的方法示例

    本文实例讲述了Python使用cx_Oracle调用Oracle存储过程的方法。分享给大家供大家参考,具体如下: 这里主要测试在Python中通过cx_Oracle调用PL/SQL。 首先,在数据库端创建简单的存储过程。 create or replace ...

    oracle存储过程unwrap解密工具.zip

    Oracle存储过程unwrap解密工具主要用于处理Oracle数据库中的加密存储过程。在Oracle数据库系统中,为了保护敏感代码或数据,开发人员有时会选择对存储过程进行加密。然而,当需要查看、调试或恢复这些加密的存储过程...

    oracle存储过程解锁

    以下是对“oracle存储过程解锁”这一主题的深入解析。 ### 标题:“oracle存储过程解锁” #### 解析: 在Oracle数据库中,存储过程是一种预先编译并存储在数据库中的SQL代码块,用于执行复杂的业务逻辑或数据处理...

    【精华志】超详细Oracle存储过程使用手册

    本手册“【精华志】超详细Oracle存储过程使用手册”深入探讨了这一主题,旨在帮助C#、ASP.NET开发者以及SQL和DBA专家更好地理解和应用存储过程。 1. **存储过程的概念与优势** - 存储过程是预编译的SQL和PL/SQL...

    帆软报表Oracle存储过程解决storeParameter1参数试用插件

    此外,对于Oracle存储过程,理解其基本概念和使用方法也是必要的。存储过程是预编译的SQL语句集合,可以封装复杂的业务逻辑,提高数据处理效率,并通过参数传递数据。在与帆软报表集成时,正确理解和调用存储过程能...

    oracle 存储过程 函数 dblink

    在这段Java代码中,我们使用了`CallableStatement`来调用Oracle存储过程`TESTA`。关键点包括: - `prepareCall`方法用于准备调用存储过程。 - 使用`setString`方法设置输入参数的值。 - 调用`execute`方法执行存储...

    oracle 存储过程 使用游标 判断2表 新增更新操作

    oracle存储过程使用游标判断2表差异,进行新增更新操作

    Oracle存储过程返回结果集

    本篇将深入探讨如何在Oracle存储过程中创建并返回一个结果集,并结合Java代码展示如何在应用程序中使用这个结果集。 首先,我们需要理解`OUT`参数的概念。在Oracle存储过程中,`IN`参数用于传递数据到过程,`OUT`...

    oracle存储过程-帮助文档

    Oracle存储过程是数据库管理系统中的一种重要特性,它允许开发者编写一系列SQL语句和PL/SQL块,形成可重复使用的代码单元。这篇博客“oracle存储过程-帮助文档”可能提供了关于如何创建、调用和管理Oracle存储过程...

    使用java实现oracle存储过程

    使用java实现oracle存储过程。 共有3个小例子。实现的功能 1、无返回值的存储过程 如 insert 2、有返回值的存储过程(非列表)select id from tab 3、返回列表 如:select * from tab 顺便鄙视下csdn,作为一个it...

    ibatis调用oracle存储过程分页

    ibatis调用oracle存储过程分页

    C# 传入自定义列表List 到Oracle存储过程

    本文将详细讲解如何在C#中使用自定义列表(List)作为参数调用Oracle存储过程,以及实现这一功能的关键技术和注意事项。 首先,我们需要了解Oracle数据库中的PL/SQL类型,例如VARCAR2、NUMBER等,它们对应于C#中的...

    ORACLE存储过程最全教程

    Oracle存储过程是数据库管理系统Oracle中的一个关键特性,它允许开发者编写一组预编译的SQL和PL/SQL语句,以实现特定的业务逻辑或数据库操作。这篇教程将深入讲解Oracle存储过程的各个方面,帮助你从基础到高级全面...

Global site tag (gtag.js) - Google Analytics