ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Oracle 存储过程调用存储过程返回结果集:TaoToken 配置与验证骨架

Oracle 存储过程调用存储过程返回结果集:TaoToken 配置与验证骨架 1. Oracle 存储过程嵌套调用返回结果集到底难在哪Oracle 存储过程调用存储过程并返回结果集是数据库开发和迁移里非常典型的一类需求。简单说就是外层存储过程Proc_Test自己不直接查表而是把查询、插入、更新、删除这些动作委托给包里的其他过程最后把多个SYS_REFCURSOR游标和影响行数一起返回给调用方。它适合谁适合正在做 Oracle 存储过程重构、数据迁移、报表接口开发或者需要在 AI 编码工具里稳定复现这套调用骨架的开发者。真正让人头疼的地方不在语法而在几个细节被调用过程的 OUT 参数类型必须和调用方声明的游标变量严格对应SYS_REFCURSOR不能随便当普通变量赋值多个结果集同时返回时客户端要按顺序逐个 FETCH迁移到别的数据库时游标语义差异更大。我试过把这类逻辑直接丢给 AI 工具生成结果经常出现游标类型不匹配、参数顺序错位的问题所以需要一个稳定的接入通道来反复验证。这篇就围绕「Oracle 存储过程调用存储过程返回结果集」这条主线先给出可复制的 TaoToken 统一 Key/API 通道配置骨架再落到 Oracle 侧的完整过程代码、调用验证动作以及常见报错排查。你可以把它当成一个能直接跟做的验证骨架而不是只讲概念的说明。2. TaoToken 前置统一 Key 与 API 通道准备在开始写 Oracle 过程之前先把 AI 工具的接入通道配好。TaoToken 在这里的作用是提供一个统一的 Key 和 API 入口让 Claude Code、Cursor、Cline 这类工具都能走同一条通道避免每个工具单独配一遍、Key 到处散落。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。你需要先拿到一个可用的 Key。进入控制台创建 API Key页面在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsole_keyutm_campaignrewrite Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后复制那串以sk-开头的字符串后面配置里会用到。注意Key 只显示一次建议创建后立刻存到本地密码管理器不要直接提交到 Git 仓库。如果你只是想在对话里验证模型对 Oracle 存储过程的理解可以直接用模型对话入口 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodels_chatutm_campaignrewrite 。如果是要长期做编码和 Agent 任务比如让工具反复生成、校验 PL/SQL建议走 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 额度更稳。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到参数不确定时优先查这里。3. 可复制配置settings.json 与 config.toml 骨架不同工具的配置文件格式不一样下面给两份最常用的骨架。核心思路一致把 base_url 指向 TaoToken 的 API 入口把 api_key 换成你自己的 Key模型名按需选择。先看 Claude Code 常用的settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: sk-你的Key, ANTHROPIC_MODEL: claude-sonnet-4-20250514 }, permissions: { allow: [Read, Write, Bash] } }再看通用型工具的config.toml[provider] name taotoken base_url https://taotoken.net/api api_key sk-你的Key model claude-sonnet-4-20250514 timeout 120 [features] stream true max_tokens 8192Claude Code 的专用接入说明在 https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 里面有更细的环境变量对照。配置时有两个坑要避开一是base_url结尾不要多加/v1工具通常会自动补二是api_key前后不要留空格否则会报 401。配好之后先别急着写 Oracle 过程用一条最简单的请求确认通道是通的。下面这段 curl 可以直接验证curl https://taotoken.net/api/v1/messages \ -H Content-Type: application/json \ -H x-api-key: sk-你的Key \ -H anthropic-version: 2023-06-01 \ -d { model: claude-sonnet-4-20250514, max_tokens: 256, messages: [ {role: user, content: 用一句话说明 Oracle SYS_REFCURSOR 的作用} ] }返回里能看到content字段有正常文本就说明 Key 和通道都没问题。这一步是整个验证骨架的地基通道不稳后面生成 PL/SQL 时断断续续会很难排查。4. Oracle 侧嵌套调用返回结果集的完整骨架现在进入正题。先定义游标类型再写被调用的过程最后写外层聚合过程。为了让骨架可运行我用一个简化的包PCK_DATAMANAGER来演示思路和原场景一致外层过程接收多个 OUT 游标和多个 OUT 行数变量内部依次调用查询、插入、更新、删除过程。第一步定义游标类型。通常放在包规范里CREATE OR REPLACE PACKAGE PCK_TYPES AS TYPE RefCursorType IS REF CURSOR; END PCK_TYPES;第二步写被调用的查询过程返回一个结果集CREATE OR REPLACE PROCEDURE Proc_Select( p_table IN VARCHAR2, p_cols IN VARCHAR2, p_where IN VARCHAR2, p_values IN VARCHAR2, p_order IN VARCHAR2, p_cursor OUT PCK_TYPES.RefCursorType ) IS v_sql VARCHAR2(4000); BEGIN v_sql : SELECT || p_cols || FROM || p_table; IF p_where IS NOT NULL THEN v_sql : v_sql || WHERE || p_where; END IF; IF p_order IS NOT NULL THEN v_sql : v_sql || ORDER BY || p_order; END IF; OPEN p_cursor FOR v_sql; END Proc_Select;第三步写外层聚合过程把多个结果集和行数一起返回CREATE OR REPLACE PROCEDURE Proc_Test( Result_Set1 OUT PCK_TYPES.RefCursorType, Result_Set2 OUT PCK_TYPES.RefCursorType, Result_rowcount1 OUT VARCHAR2, Result_rowcount2 OUT VARCHAR2 ) IS BEGIN PCK_DATAMANAGER.Proc_Select( T_RTU, RTU_ID,RTU_NAME, NULL, NULL, RTU_ID, Result_Set1); PCK_DATAMANAGER.Proc_Select( T_OPERATOR, OPERATOR_CODE,GROUP_NAME, NULL, NULL, OPERATOR_CODE, Result_Set2); PCK_DATAMANAGER.Proc_InsertInto( T_RTU, RTU_ID,RTU_NAME, 11,华城帝国, Result_rowcount1); PCK_DATAMANAGER.Proc_Update( T_RTU, RTU_NAME, 华城帝国之都, RTU_ID, 11, Result_rowcount2); END Proc_Test;这里的关键点外层过程声明了几个 OUT 游标被调用过程就必须按相同顺序、相同类型把游标 OPEN 出来。SYS_REFCURSOR本质是一个指向结果集的指针调用方拿到后要逐个 FETCH不能一次性读多个。5. 验证请求与成功结果过程写好后用一段匿名块验证。注意游标要按声明顺序接收行数变量用VARCHAR2接DECLARE v_cur1 PCK_TYPES.RefCursorType; v_cur2 PCK_TYPES.RefCursorType; v_cnt1 VARCHAR2(50); v_cnt2 VARCHAR2(50); v_id VARCHAR2(50); v_name VARCHAR2(100); BEGIN Proc_Test(v_cur1, v_cur2, v_cnt1, v_cnt2); LOOP FETCH v_cur1 INTO v_id, v_name; EXIT WHEN v_cur1%NOTFOUND; DBMS_OUTPUT.PUT_LINE(SET1: || v_id || - || v_name); END LOOP; CLOSE v_cur1; LOOP FETCH v_cur2 INTO v_id, v_name; EXIT WHEN v_cur2%NOTFOUND; DBMS_OUTPUT.PUT_LINE(SET2: || v_id || - || v_name); END LOOP; CLOSE v_cur2; DBMS_OUTPUT.PUT_LINE(插入行数: || v_cnt1); DBMS_OUTPUT.PUT_LINE(更新行数: || v_cnt2); END;执行前记得SET SERVEROUTPUT ON。成功时你会看到类似输出SET1: 11 - 华城帝国 SET2: LIJC - SUPERGROUP 插入行数: 1 更新行数: 1如果结果集为空但行数正常说明查询条件或表数据有问题不是游标本身的问题。如果行数是空字符串检查被调用过程里是否真的给 OUT 参数赋了值。6. 本篇常见错排查报错一PLS-00306 参数数量或类型错误。最常见的原因是外层过程声明的游标类型和被调用过程不一致。比如外层用SYS_REFCURSOR被调用过程用自定义RefCursorTypeOracle 会认为类型不匹配。统一用同一个包里的类型定义即可。报错二ORA-01000 超出最大打开游标数。多个结果集返回时如果调用方 FETCH 完没有CLOSE游标会一直占用。每个 OUT 游标用完必须显式关闭匿名块里逐个 CLOSE 是硬性要求。报错三ORA-06502 数值或值错误。行数变量用VARCHAR2接收时如果被调用过程返回的是 NUMBER隐式转换可能失败。建议在过程内部统一TO_CHAR再赋值或者调用方用 NUMBER 类型接收。报错四结果集顺序错乱。多个 OUT 游标是按位置对应的不是按名字。调用时参数顺序写错就会把 A 的结果集塞进 B。建议在过程注释里标明每个游标对应的业务含义。报错五AI 工具生成的 PL/SQL 跑不通。这类问题多半是模型对SYS_REFCURSOR的 OPEN FOR 动态 SQL 理解偏差。可以在模型对话入口 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodels_chatutm_campaignrewrite 里贴上报错原文让它逐行对照修正。如果是要长期批量生成和校验存储过程走 Coding Plan 更省心。排查时有个实用技巧先把外层过程简化成只调用一个查询过程确认单个结果集能返回再逐步加回插入、更新和第二个游标。这样能把问题范围快速缩小到某一个被调用过程。7. 接入通道与后续动作整套骨架跑通后你会发现真正花时间的不是写过程而是反复验证和排错。把 TaoToken 的 Key 配好之后Claude Code、Cursor 这类工具就能稳定地帮你生成、审查 PL/SQL不用每次重新配环境。API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 接入细节查文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。后续你可以在这个骨架上继续扩展把Proc_Select换成带绑定变量的版本避免 SQL 注入把行数变量改成 NUMBER 类型减少转换或者把多个结果集封装成一个 JSON 返回给上层应用。每改一步都用第 5 节的匿名块验证一次确认游标和行数都对得上再往下走。
返回列表