Oracle 11g中SQL存储过程编写方法及游标返回教程
时间:2026-08-17 | 作者:骑光打字机 | 阅读:0必须用 SYS_REFCURSOR 而非普通游标,因其是弱类型引用游标,可跨作用域传递并由调用方fetch;普通游标静态绑定、无法传出过程边界。
直接用 SYS_REFCURSOR 作 OUT 参数,就能让存储过程返回结果集——不是把数据复制出来,而是把游标句柄交出去,调用方自己 fetch。
为什么必须用 SYS_REFCURSOR 而不是普通游标变量
普通的显式游标,例如 CURSOR c IS SELECT ...,本质上属于静态绑定。
它的使用范围被限定在声明它的那个 PL/SQL 块里,只能在那里完成 open、fetch 和 close。一旦越过过程边界,就无法再继续传递。
相比之下,SYS_REFCURSOR 属于弱类型引用游标,更像一个指针。它不会预先锁定查询结果结构。
同一个变量既可以先 OPEN FOR SELECT * FROM t1,也可以随后再指向 OPEN FOR SELECT x,y FROM t2。同时,它还能跨作用域传递,客户端工具像 JDBC、SQL Developer、SQL*Plus 也都能直接识别并展示它返回的结果集。
常见错误现象:PLS-00382: expression is of wrong type —— 误把普通游标变量当 OUT 参数传;或声明成 IN OUT 却没初始化;或在声明区就写 OPEN(语法非法)。
SYS_REFCURSOR必须声明为OUT(不能是IN或IN OUT)OPEN ... FOR必须写在BEGIN块里,不能放在声明区- 不能对
SYS_REFCURSOR直接FETCH—— 它本身不是结果,只是句柄,fetch 操作由调用方完成
CREATE OR REPLACE PROCEDURE 中怎么声明和打开 SYS_REFCURSOR
声明格式固定:p_result OUT SYS_REFCURSOR。
OPEN p_result FOR 后面可以跟任意合法 SELECT,支持绑定变量、子查询、甚至动态 SQL。
示例:
CREATE OR REPLACE PROCEDURE get_user_data( p_dept_id IN NUMBER, p_resultOUT SYS_REFCURSOR ) IS BEGIN OPEN p_result FOR SELECT id, name, salary FROM users WHERE dept_id = p_dept_id AND status = 'ACTIVE'; END;
注意点:
- 查询语句中用
=而非:=—— 这是 SQL,不是赋值 - 若需动态 SQL(如拼表名),用
EXECUTE IMMEDIATE '...' INTO ...不适用;正确方式是OPEN p_result FOR sqlstr USING bind_var - Oracle 11g 支持
USING绑定变量,避免 SQL 注入,也提升硬解析复用率
调用时怎么拿到并遍历这个游标结果
不能在另一个存储过程中直接 FETCH —— 那是对本地游标的用法。
这里要分两步:先执行过程获取句柄,再从该句柄读数据。通常这个操作发生在匿名块或客户端。
PL/SQL 匿名块调用示例:
BEGIN get_user_data(p_dept_id => 10, p_result => :cur_out); END;
然后在 SQL Developer 或 PL/SQL Developer 的 Variables 面板里,把 cur_out 类型设为 Cursor,点 Value 栏右侧图标展开结果。
JDBC 中对应的是:
CallableStatement.registerOutParameter(, Types.OTHER)cs.execute()ResultSet rs = cs.getResultSet()
容易踩的坑:
- SQL*Plus 默认不显示游标结果,需提前执行
SET SERVEROUTPUT ON并配合DBMS_OUTPUT.PUT_LINE手动输出(但一般不用——直接查游标更直观) - MyBatis 中若用
resultType="map"接收,需确保 mapper XML 中statementType="CALLABLE"且参数mode="OUT" - 游标未被消费完就断开连接?Oracle 会自动 close,但长期持有大结果集仍可能撑爆 PGA 内存
关键理解:返回的不是表,而是句柄
真正棘手的,往往并不在于存储过程怎么写,而在于调用方有没有把这件事理解透。
它返回的不是“现成的一张表”,而是“一个可以遍历的句柄”。
这意味着,没有 schema 元信息,不会帮你自动做类型转换,结果顺序也没有兜底保证。最终都得靠调用方严格按约定来接。
尤其一旦涉及跨语言调用,Types.OTHER 和 getResultSet() 这组搭配只要稍微没对上,就很容易直接静默失败。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- 迅捷路由器怎么调信号最强,设置时要注意什么?
- 时间:2026-08-27
-
- vivo浏览器怎么卸不掉?原因和解决方法在这里
- 时间:2026-08-27
-
- OPPO R11s黑屏了,怎么强制恢复出厂设置?
- 时间:2026-08-27
-
- 飞利浦显示器包装盒有生产日期和保修期吗?怎么看?
- 时间:2026-08-27
-
- 联想新平板开机必须联网吗?怎么做?
- 时间:2026-08-27
-
- 平板横竖屏切换设置与问题解决
- 时间:2026-08-27
-
- 移动电源容量怎么测?要准备哪些工具?
- 时间:2026-08-27
-
- 荣耀90 Pro防水吗?防水级别多少?怎么用才安全
- 时间:2026-08-27
精选合集
更多大家都在玩
大家都在看
更多-
- 以下哪种食材被称为“地下苹果” 蚂蚁庄园今日答案9.18
- 时间:2026-09-17
-
- 蚂蚁庄园今天答题答案2026年9月18日
- 时间:2026-09-17
-
- 蚂蚁庄园答题今日答案2026年9月18日
- 时间:2026-09-17
-
- 蚂蚁庄园小课堂2026年9月18日最新题目答案
- 时间:2026-09-17
-
- 小鸡答题今天的答案是什么2026年9月18日
- 时间:2026-09-17
-
- 蚂蚁庄园每日答题答案2026年9月18日
- 时间:2026-09-17
-
- 蔬菜洗完掉色,说明是被染色了,是真的吗 蚂蚁庄园今日答案9月18日
- 时间:2026-09-17
-
- 满襟蜡绘花纹巧染就花纹当绣裳说的是哪种传统技艺 蚂蚁新村今日答案2026.9.17
- 时间:2026-09-17
