转载自:http://sishuok.com/forum/blogPost/list/488.html
本文主要是总结 如何实现 JDBC调用Oracle的存储过程,从以下情况分别介绍:
- [1]、只有输入IN参数,没有输出OUT参数
- [2]、既有输入IN参数,也有输出OUT参数,输出是简单值(非列表)
- [3]、既有输入IN参数,也有输出OUT参数,输出是列表
- [4]、输入输出参数是同一个(IN OUT)
【准备工作】
创建一个测试表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参数
存储过程 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.
符号条件的查询结果 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.
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.
符号条件的查询结果 count := 1
------- Test End.
相关推荐
jdbc执行存储过程jdbc执行存储过程jdbc执行存储过程
本篇将详细介绍如何使用JDBC连接Oracle数据库并执行存储过程。 首先,我们需要理解JDBC的基本概念。JDBC是Java平台的标准API,它允许Java程序与各种数据库进行通信。通过JDBC,我们可以创建数据库连接、发送SQL语句...
5. **执行存储过程**:使用`CallableStatement`的`execute()`方法执行存储过程。 ```java cs.execute(); ``` 6. **获取结果**:如果存储过程有输出参数或返回结果集,可以使用`getXXX()`方法获取。例如,获取...
在Java中,JDBC提供了一套API来执行存储过程。主要涉及以下几个步骤: 1. **加载驱动**:使用`Class.forName()`方法加载对应的数据库驱动,例如`Class.forName("com.mysql.jdbc.Driver")`对于MySQL。 2. **建立...
5. **执行存储过程**:调用`CallableStatement.execute()`方法执行存储过程。如果存储过程返回结果集,可以使用`ResultSet`对象处理。 ```java ResultSet rs = cs.executeQuery(); while (rs.next()) { // 处理...
JDBC存储过程调用示例,详细描述了存储过程调用的过程。
android通过jdbc方式连接mysql,并执行存储过程。连接数据库部分最好新建一个线程来实现和主线程分开。编译之前确定添加了mysql-connector-java-5.0.8-bin库否则会出错
// 执行存储过程 ``` 这里的`P_GETALLRESOURCE()`是一个假设存在的DB2存储过程,其功能可能是返回所有资源的信息。`prepareCall`方法用于创建一个可以执行SQL存储过程的`CallableStatement`对象。 #### 四、处理...
5. **执行存储过程**:调用`CallableStatement.execute()`方法执行存储过程。 6. **处理结果**:如果存储过程有返回结果,可以使用`CallableStatement.getObject()`等方法获取结果。 7. **关闭资源**:最后,记得...
4. 执行存储过程:调用`CallableStatement.execute()`方法执行存储过程。 5. 获取结果:对于输出参数,使用`getXXX()`方法获取值。如果是查询结果,可以使用`ResultSet`对象处理返回的数据。 封装JDBC调用存储过程...
`MySqlUtil.java`可能包含与MySQL数据库交互的通用工具类,`MySqlJdbcTest.java`和`MySqlTest.java`则可能包含了具体的测试用例,比如创建触发器、执行存储过程、备份和恢复数据的代码实例。 总之,通过JDBC,Java...
接下来,创建`CallableStatement`对象,它是用于执行存储过程和函数的。格式如下: ```java CallableStatement cs = conn.prepareCall("{ call proc_name(?, ?) }"); ``` 这里的`{ call proc_name(?, ?) }`是SQL的...
总的来说,使用JDBC操作Oracle的存储过程返回值涉及了JDBC的基本操作,包括加载驱动、建立连接、创建CallableStatement、设置参数、执行存储过程、获取返回值以及释放资源。理解这些步骤对于开发与Oracle数据库交互...
3. 创建CallableStatement对象:`CallableStatement`是JDBC提供用于执行存储过程的接口。我们可以使用`Connection.prepareCall()`方法创建一个`CallableStatement`对象,并传入存储过程的SQL调用格式。对于大多数...
最后通过`execute`方法执行存储过程。 #### 四、依赖库 在使用JDBC调用存储过程时,需要确保项目中有以下依赖: - JDK 1.4及以上版本提供的相关JAR包。 - Oracle提供的JDBC驱动包`ojdbc14.jar`。 - NLS_CHARSET12....
PLSQL jdbc调用存储过程(入门)
5. 执行存储过程,调用CallableStatement的`execute`或`executeQuery`方法。 6. 获取结果,如果存储过程有返回值,可以使用`getXXX`方法(如getInt, getString等)获取输出参数值。如果有结果集,可以迭代处理。 ...
- **`execute()` 方法**:用于执行存储过程或函数。如果第一个结果是 `ResultSet` 对象,则返回 `true`;如果是更新计数或无结果,则返回 `false`。 - **`registerOutParameter(int parameterIndex, int sqlType...