jdbc中调用oracle存储过程

本文演示了如何使用SQL创建表、插入数据、创建存储过程,并通过JDBC调用存储过程来获取数据。重点展示了SQL语法及JDBC在Java中的应用。

1、创建表:

     create table stud(
             sid int,
            sname varchar2(50)
     )
     并插入一条数据
     insert into stud values(1,'Tom')

2、创建存储过程
 
    --创建存储过程
    create or replace procedure pro_select_name(
            v_sid in stud.sid%type,
            v_sname out stud.sname%type
     )
     --声明区
     is
     --执行体
     begin
              select sname into v_sname from stud where sid = v_sid;
      
     --异常处理
     exception

            when others then
            dbms_output.put_line(sqlcode||sqlerrm);
     end;

3、jdbc中调用
 
     import java.sql.CallableStatement;
     import java.sql.Connection;
     import java.sql.DriverManager;
     import java.sql.Types;

     public class TestPro {
 
            public void test(){
            Connection con = null;
            CallableStatement cst = null;
            try{
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                   //下面的tan是数据库名,默认是orcl,love是访问密码,默认是tiger

                   //1521是端口号,默认是1521
                    con = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:tan","scott","love");
                    String sql = "{call  pro_select_name(?,?)}";
                    cst = con.prepareCall(sql);
                    cst.setInt(1, 1);
                    cst.registerOutParameter(2, Types.VARCHAR);
                    cst.execute();
   
                    String name = cst.getString(2);
                    System.out.println(name);
   
             }catch(Exception e){
                    e.printStackTrace();
             }finally{
            try{
                    if(cst != null){
                            cst.close();
                    }
                   if(con != null){
                             con.close();
                   }
              }catch(Exception e){
                             e.printStackTrace();
           }
   
        }
 }
 /**
  * @param args
  */
         public static void main(String[] args) {
                TestPro tp = new TestPro();
                tp.test();
         }

}

 


运行结果:
Tom

 
 

 

<think>好的,我现在需要帮助用户了解如何在Java JDBC调用Oracle存储过程。用户已经提供了几个相关的引用,我需要仔细分析这些内容并整理出一个清晰的回答。 首先,我应该回顾用户提供的引用内容。引用[1]给出了一个调用存储过程的Java代码示例,包括连接数据库、准备语句、执行和关闭资源。引用[2]提到在传入数组时遇到的问题,特别是类型转换错误,这可能涉及到使用Oracle特定的连接类型。引用[3]讨论了使用存储过程的优缺点,但在回答中可能不需要深入这一点,但需要注意维护问题。引用[4]特别指出创建和执行存储过程的环境差异,以及需要引入依赖和数据源配置。 接下来,我需要按照用户的要求,结构清晰地分步骤说明调用过程。用户要求回答真实可靠,所以需要确保每个步骤都正确无误,并参考提供的引用内容。 第一步是建立数据库连接。引用[1]和[4]都提到了使用DriverManager.getConnection,这里需要提醒用户加载驱动,但OracleJDBC驱动在较新版本中可能自动加载。不过,为了兼容性,可能需要Class.forName,但Java 6之后不需要,这点可能需要确认。 第二步是准备调用语句。根据引用[1],使用CallableStatement和{call ...}语法。对于参数,特别是IN和OUT参数,需要说明如何注册。例如,使用cs.setString(1, "value")和cs.registerOutParameter(2, Types.VARCHAR)。 第三步是执行存储过程,如引用[1]中的cs.execute()。然后处理结果,如果有结果集的话,使用getResultSet()遍历,或者获取输出参数的值。 第四步是关闭资源,这在所有数据库操作中都很重要,引用[1]的finally块中关闭了ResultSet、CallableStatement和Connection。 另外,用户可能遇到类型转换问题,如引用[2]中的数组问题。这时候需要说明如何处理Oracle特定的数组类型,比如使用ARRAY类,可能需要将连接转换为OracleConnection,这可能导致类型转换错误,特别是当使用连接池时,如PoolGuardConnectionWrapper无法转换为OracleConnection。解决方案可能是先从连接中获取原生连接,或者配置连接池以返回OracleConnection。 引用[4]提到在命令行执行存储过程的需要,以及依赖和数据源配置。所以在步骤中可能需要提醒用户添加Oracle JDBC驱动依赖,比如ojdbc8.jar,并确保正确配置数据源。 此外,需要给出示例代码,涵盖基本调用、带输入输出参数的情况,以及处理数组参数的情况。例如,数组参数的示例需要展示如何创建Oracle ARRAY并传递给存储过程。 最后,生成相关问题,如参数处理、数组传参、常见错误、事务处理、性能比较等,这些可以帮助用户进一步学习。 需要检查所有LaTeX格式是否正确,行内公式用$...$,独立公式用$$...$$,但在这个回答中可能不需要数学公式,所以可能不需要使用。但用户示例中有代码块,需要正确使用三个反引号包裹,并标明语言。 总结步骤: 1. 建立连接,加载驱动,处理URL。 2. 准备CallableStatement,使用正确的语法。 3. 设置输入参数,注册输出参数。 4. 执行并处理结果。 5. 关闭资源。 6. 示例代码,包括基本调用、输入输出参数、数组处理。 7. 注意事项,如依赖、连接类型转换、执行环境。 8. 相关问题。 现在需要将这些内容组织成结构清晰的中文回答,确保每个部分引用正确的来源,并在末尾添加引用标识。例如,处理数组时的类型转换问题引用[2],关闭资源引用[1]等。</think>### Java JDBC调用Oracle存储过程分步教程 #### 一、基础调用步骤 1. **建立数据库连接** 使用`DriverManager.getConnection`连接Oracle数据库,需指定连接字符串、用户名和密码: ```java Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:orcl", "username", "password" ); ``` > 注意:需引入Oracle JDBC驱动依赖(如`ojdbc8.jar`)[^4]。 2. **准备调用语句** 使用`CallableStatement`定义存储过程调用语法,格式为`{call 过程名(参数列表)}`: ```java String sql = "{call my_procedure(?, ?)}"; CallableStatement cs = conn.prepareCall(sql); ``` 3. **设置输入/输出参数** - **输入参数**:通过`setXxx`方法设置值: ```java cs.setString(1, "input_value"); // 第一个参数为String类型输入 ``` - **输出参数**:需注册参数类型: ```java cs.registerOutParameter(2, Types.VARCHAR); // 第二个参数为VARCHAR类型输出 ``` 4. **执行存储过程** 调用`execute()`方法执行: ```java cs.execute(); ``` 5. **处理返回结果** - 若存储过程返回结果集: ```java ResultSet rs = cs.getResultSet(); while (rs.next()) { System.out.println(rs.getString("column_name")); } ``` - 若为输出参数: ```java String output = cs.getString(2); // 获取第二个输出参数的值 ``` 6. **关闭资源** 按`ResultSet → CallableStatement → Connection`顺序关闭资源[^1]: ```java rs.close(); cs.close(); conn.close(); ``` --- #### 二、完整示例代码 ```java import java.sql.*; public class CallProcedureDemo { public static void main(String[] args) { try (Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:orcl", "user", "pass"); CallableStatement cs = conn.prepareCall("{call get_employee(?, ?)}")) { // 设置输入参数 cs.setInt(1, 101); // 注册输出参数 cs.registerOutParameter(2, Types.VARCHAR); // 执行并获取结果 cs.execute(); System.out.println("员工姓名: " + cs.getString(2)); } catch (SQLException e) { e.printStackTrace(); } } } ``` --- #### 三、处理特殊数据类型 1. **数组参数传递** 若需传递数组(如`OracleTypes.ARRAY`): ```java // 获取Oracle原生连接 OracleConnection oraConn = conn.unwrap(OracleConnection.class); // 创建数组描述符 ArrayDescriptor desc = ArrayDescriptor.createDescriptor("ARRAY_TYPE", oraConn); // 构造数组对象 Object[] values = {1, 2, 3}; ARRAY array = new ARRAY(desc, oraConn, values); // 设置数组参数 cs.setArray(1, array); ``` > 注意:连接池返回的包装类需通过`unwrap()`转换,否则会抛出类型转换异常[^2]。 --- #### 四、注意事项 1. **依赖配置** 确保项目中包含`ojdbc.jar`,若使用Maven: ```xml <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>21.1.0.0</version> </dependency> ``` 2. **存储过程调试** Oracle存储过程建议在命令行窗口(如SQL*Plus)中执行测试,避免在SQL窗口出现无效语句错误[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值