如何从Java调用带游标的Oracle存储过程

老静酱_3225

老静酱_3225

2026-07-21

514人浏览

原创

callablestatement 是 java 调用 oracle 游标存储过程的核心,必须注册 oracle.jdbc.oracletypes.cursor 类型并用 getobject() 获取 resultset;游标需在包中定义 ref cursor 类型,不可在匿名块或独立过程中返回;参数索引从 1 开始,resultset 必须显式 close 以防 ora-01000 错误。

如何从java调用带游标的oracle存储过程

CallableStatement 是 Java 调用带游标的 Oracle 存储过程的核心入口,但直接调用会失败——必须显式注册 OracleTypes.CURSOR 类型,并用 getObject() 或 getCursor() 提取 ResultSet。否则你会拿到 null 或抛出 ClassCastException。

存储过程必须定义在包里,且游标类型要声明为 REF CURSOR

Oracle 不允许在匿名块或独立过程里直接返回游标;必须通过包(package)定义公共游标类型。常见错误是把 TYPE my_cursor IS REF CURSOR 写在过程体里,或者和包体一起执行——这会导致编译失败。

  • 包头定义类型:CREATE OR REPLACE PACKAGE pkg_demo AS TYPE refcur IS REF CURSOR; PROCEDURE proc_list(p_id IN NUMBER, p_out OUT refcur); END;
  • 包体实现 OPEN:CREATE OR REPLACE PACKAGE BODY pkg_demo AS PROCEDURE proc_list(p_id IN NUMBER, p_out OUT refcur) IS BEGIN OPEN p_out FOR SELECT id, name FROM users WHERE dept_id = p_id; END; END;
  • 不能在包外建独立过程返回游标;也不能在包体里重复定义游标类型

registerOutParameter 必须用 oracle.jdbc.OracleTypes.CURSOR,不是 Types.OTHER

用 java.sql.Types.OTHER 会导致 JDBC 驱动无法识别游标结构,返回空对象或报 ORA-06550 错误。Oracle JDBC 驱动要求明确使用其扩展类型常量。

java-enterprise
java-enterprise

Java企业开发专家,专注于Spring Boot、微服务架构和JVM优化。适用于:Java语言掌握、

下载
  • 正确写法:cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
  • 错误写法:cs.registerOutParameter(2, Types.OTHER); 或 cs.registerOutParameter(2, Types.JAVA_OBJECT);
  • 注意导入:import oracle.jdbc.OracleTypes;,不是 java.sql.Types
  • 参数索引从 1 开始,和 SQL 中 ? 位置严格对应

获取结果集后必须手动 close(),尤其在连接池环境下

游标底层绑定数据库会话资源,JDBC 不会在 ResultSet.close() 时自动释放游标句柄。如果漏关,连接池中的连接可能被锁住,后续请求卡死或报 ORA-01000: maximum open cursors exceeded。

  • 推荐用 try-with-resources 包裹 ResultSet:try (ResultSet rs = (ResultSet) cs.getObject(2)) { ... }
  • 不要在存储过程中执行 CLOSE p_out —— JDBC 会接管生命周期,显式 CLOSE 反而引发 invalid cursor
  • 如果用 cs.getCursor(2),它只是 getObject(2) 的语义别名,行为完全一致,无需额外处理
  • 确保 Connection 和 CallableStatement 也按顺序关闭,否则游标资源释放延迟

字段名大小写敏感,且不能依赖列序号跳过元数据检查

Oracle 默认将字段名转为大写,而 Java ResultSet.getString("name") 在未启用 oracle.jdbc.mapUpperCaseToLowerCase 连接属性时会找不到列——报 Invalid column name。

  • 安全做法:先用 rs.getMetaData().getColumnLabel(i) 确认实际列名
  • 或统一用大写访问:rs.getString("NAME")、rs.getInt("ID")
  • 避免用 rs.getString(1) 这类序号访问,一旦 SQL 改了 SELECT 顺序就崩
  • 别在循环里反复调用 rs.getMetaData(),性能差;提前提取一次即可
游标本质是服务器端的一次性结果集句柄,Java 层没有缓存或重放能力。只要 rs.next() 返回 false,这个游标就彻底读完了,再调一次 rs.beforeFirst() 会抛异常——这点和 MySQL 的可滚动 ResultSet 完全不同。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10157

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7302

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6412

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1104

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

908

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1336

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2669

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19991

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1195

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程