Oracle存储过程必须通过OUT SYS_REFCURSOR传递游标句柄,调用方自行FETCH;OPEN必须在BEGIN块内,不可在声明区;禁止过程内FETCH/CLOSE;多分支须确保每个路径都OPEN同一参数;弱类型易致运行时类型错误,建议强类型游标提升稳定性。

Oracle 存储过程不能直接把结果集“吐”给前端,必须通过 SYS_REFCURSOR 作为 OUT 参数传递游标句柄——前端(或中间层)拿到这个句柄后,自己去 fetch 数据。这是 Oracle 的设计约束,不是写法问题。
存储过程中声明和打开 SYS_REFCURSOR 的正确姿势
必须用 OUT SYS_REFCURSOR 声明参数,不能是 IN 或 IN OUT;OPEN ... FOR 必须写在 BEGIN 块里,不能放在声明区。
-
OPEN p_result FOR SELECT * FROM emp WHERE deptno = p_dept_id;支持绑定变量、子查询、动态 SQL(用EXECUTE IMMEDIATE) - 不要在过程里对
p_result做FETCH或CLOSE——它只是个指针,生命周期交给调用方 - 如果过程有多个分支,每个分支都必须
OPEN同一个OUT参数,否则调用方可能拿到未初始化的游标,报ORA-01001: invalid cursor
PL/SQL 匿名块调用时怎么接收并遍历
在 SQL*Plus / SQL Developer 里测试,必须用冒号前缀声明绑定变量::cur_out,且需提前执行 SET SERVEROUTPUT ON 才能看到输出。
HISUI 前端框架基础开发指南。HISUI 是基于 easyui 二次开发的 jQuery UI 组件库,专为医疗信息系统设计。当涉及 HISUI 组件开发、jQuery easyui 表格/表单/布局/窗口、医疗系统前端页面编写时使用此 skill。 涵盖 40 个组件的官方文档参考,支持声明式与编程式两种初始化方式,提供 $cm/$m 数据访问方法。
- 声明变量要匹配类型:
cur_var SYS_REFCURSOR; - 不能直接
FOR rec IN cur_var LOOP—— 这语法只适用于显式游标,SYS_REFCURSOR必须先FETCH INTO一个已定义结构的变量(如emp%ROWTYPE)或使用DBMS_SQL动态处理 - 务必在循环结束后
CLOSE cur_var;,否则下次调用可能触发ORA-01000: maximum open cursors exceeded
Java/JDBC 调用时 registerOutParameter 的关键点
MyBatis 或原生 JDBC 都必须显式注册游标类型,否则 getResultSet() 会返回 null 或抛 ORA-17004。
- JDBC 层:用
registerOutParameter(1, OracleTypes.CURSOR),不是Types.OTHER - MyBatis Mapper XML 中,
statementType="CALLABLE"+jdbcType="CURSOR"缺一不可;resultType="map"只能用于自动映射列名,但无法保证字段顺序稳定 - 别依赖 MyBatis 自动关闭游标——应用层拿到
ResultSet后,必须手动rs.close(),否则连接池里的物理游标不会释放
容易被忽略的弱类型陷阱
SYS_REFCURSOR 不校验列结构,编译期完全放行。同一个过程,不同参数可能打开结构完全不同的查询,但调用方仍用同一套 FETCH INTO 逻辑,就会在运行时报 PLS-00382: expression is of wrong type 或 ORA-06502。
- 前端或 Java 层不能假设列顺序固定——要用列名取值(
rs.getString("EMP_NAME")),而不是下标(rs.getString(1)) - 如果过程可能返回多种结果集,建议在包头统一定义强类型游标(
TYPE t_cur IS REF CURSOR RETURN emp%ROWTYPE),牺牲一点灵活性换掉运行时崩溃风险 - 所有异常路径(比如
EXCEPTION块)里,如果游标已打开,必须CLOSE,否则泄漏不可逆
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










