十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Oracle 存储过程返回 ref cursor 怎么写?TaoToken 供 Key,Codex 对照 pkg_test 排查

Oracle 存储过程返回 ref cursor 怎么写?TaoToken 供 Key,Codex 对照 pkg_test 排查 Oracle 存储过程返回 ref cursor 怎么写TaoToken 供 KeyCodex 对照 pkg_test 排查写 Oracle 存储过程返回数据集真正让人卡住的往往不是那条 select 语句而是包声明、包体、匿名块这三段之间的类型与签名必须严格对齐。pkg_test 这个最小例子里有 type myrctype is ref cursor、有 display(p_empno char, p_rc out myrctype) 这样的出参过程还有匿名块里 w_rc fetch into w_empname 的循环读取任何一处参数名、类型、绑定变量对不上编译或运行就会直接报错。本文按接入配置的视角来写先把 Codex 接到 TaoToken官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcodex-config 拿到 Key 和 Base URL再把 pkg_test 三段代码贴给 Codex 逐段核对最后回到本地 SQL*Plus 里跑 display(0001, w_rc) 验证 ref cursor 到底有没有按预期返回数据。TaoToken 在这里只负责提供模型调用的 Key 与 Base URL它不替代 Oracle 存储过程本身也不会替你编译包代码正确与否仍以数据库里的编译结果和实际取数结果为准。一、三段对不上pkg_test 里 ref cursor 最常卡的现场先还原场景。目标很简单写一个存储过程把一张 student 表里符合条件的记录以 ref cursor 的形式返回给调用方由调用方自己循环 fetch。这个目标会拆成三段代码分别放在三个地方执行第一段是包声明只写接口不写实现create or replace package pkg_test as type myrctype is ref cursor; procedure display(p_empno char, p_rc out myrctype); end pkg_test; /第二段是包体写 procedure display 的具体逻辑。当 p_empno 为空时直接打开全表游标不为空时用动态 SQL 加绑定变量过滤create or replace package body pkg_test as procedure display(p_empno char, p_rc out myrctype) is v_sql varchar2(200); begin if p_empno is null then open p_rc for select emp_name from student; else v_sql : select emp_name from student where emp_no :w_empno; open p_rc for v_sql using p_empno; end if; end display; end pkg_test; /第三段是匿名块调用声明一个包内类型的变量接收游标再一条条取出来打印set serveroutput on declare w_rc pkg_test.myrctype; w_empname student.emp_name%type; begin pkg_test.display(0001, w_rc); loop fetch w_rc into w_empname; exit when w_rc%notfound; dbms_output.put_line(w_empname); end loop; close w_rc; end; /三段代码单看都不难问题在于它们之间有三条隐式契约。第一条契约是类型归属。myrctype 定义在包的声明里所以匿名块中声明变量必须写成 pkg_test.myrctype而不是直接写 myrctype也不能写成 sys_refcursor 混用否则要么报标识符未声明要么游标类型不匹配。第二条契约是过程签名。包声明里的 display(p_empno char, p_rc out myrctype) 与包体里的过程头必须完全一致参数名、参数顺序、参数模式 out、类型 myrctype任何一项不同包体就会编译不过典型报错是 PLS-00323。第三条契约是绑定变量。动态 SQL 字符串里写的是 :w_empno那么 open ... for v_sql using p_empno 里的 using 后面就必须按顺序、按个数、按类型把值补上。少一个、多一个、类型对不上都会在运行时抛 ORA-01008 或 ORA-06550 一类错误。这也是三段代码里最容易出错、又最难靠肉眼发现的地方因为编译器不会在编译期替你检查字符串里的冒号变量。二、TaoToken 前置注册、建 Key、Codex 的接入位置既然痛点集中在“三处细节对不上”和“动态 SQL 绑定易错”一个可行的做法是把这三段代码交给 Codex让它逐段做一致性核对类型名是否统一、过程签名是否一致、using 的参数是否与 :w_empno 一一对应。这一步需要模型调用能力而 Codex 需要配置一个可用的模型提供方。接入动作本身很短按顺序做三件事第一步打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcodex-config 完成注册进入控制台创建一个 API Key。Key 只在创建时完整展示复制下来单独保存。第二步记下接口地址https://taotoken.net/api 。注意这个地址后面不要接 /v1因为 Codex 的 provider 配置会自己拼接具体路径也不要带任何 UTM 查询参数UTM 是给网页跳转统计用的写进 base_url 会变成请求路径的一部分导致 404 或参数污染。第三步在 Codex 的模型配置里把这个地址填进去。Codex 读的是 config.toml下一节给出可直接复制的完整片段。这里再强调一次边界TaoToken 提供的是 Key 和 Base URL也就是让 Codex 能发出模型请求它不会替你编译 pkg_test也不会在 Oracle 里建表建包。配通之后代码怎么写、绑定变量怎么对、游标怎么 fetch仍然由你在数据库里决定并验证。三、可复制配置config.toml pkg_test 三段完整代码Codex 的配置文件通常在用户目录下的 ~/.codex/config.toml。用自定义 provider 的方式接 TaoToken可以写成下面这样model MODEL_ID model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat把 model 换成你在控制台看到的模型 ID把 Key 放进环境变量避免明文写进配置文件export TAOTOKEN_API_KEYYOUR_API_KEY如果是在 Windows 下用系统环境变量面板新建同名变量或者在当前会话里设置对应变量效果等价。配置完成后重新打开一个终端让 Codex 重新读取 config.toml 与环境变量。配置生效后就可以把 pkg_test 的三段代码整段贴给 Codex并明确提问方向例如请核对包声明与包体的过程签名是否完全一致参数名、参数模式、类型都逐项比对请核对匿名块里 w_rc 的类型是否用了包内限定名 pkg_test.myrctype请核对 open p_rc for v_sql using p_empno 与字符串中的 :w_empno 是否一一对应是否存在多余或缺失的绑定请指出 fetch w_rc into w_empname 的循环里%notfound 的判断位置是否会导致最后一行数据被漏掉或多打一行空值。这类提问给的是比对规则而不是让模型凭空生成代码得到的结果更容易落地核对。特别提醒模型给出的修改建议只是参考最终仍要回到 Oracle 里编译执行。四、验证SQL*Plus 跑 display(0001, w_rc)再用 Codex 复核配置通了不等于代码对了验证必须分两层。第一层是连通性验证。在终端里确认 Codex 能正常发起请求比如给它一句简单指令看是否有正常返回而不是 401、403 或连接超时。这一步只证明 Key 和 Base URL 配对了不证明 SQL 正确。第二层是数据库验证。打开 SQL*Plus用你的账号连上目标库按顺序执行-- 1. 先编译包声明 pkg_test_spec.sql -- 2. 再编译包体 pkg_test_body.sql -- 3. 检查编译状态 select object_name, object_type, status from user_objects where object_name PKG_TEST;status 必须是 VALID如果有 INVALID先看 user_errors 里的具体行号和报错文本select name, type, line, position, text from user_errors where name PKG_TEST order by type, line;确认包和包体都有效之后再执行匿名块跑 display(0001, w_rc) 这条调用路径set serveroutput on size 1000000 declare w_rc pkg_test.myrctype; w_empname student.emp_name%type; begin pkg_test.display(0001, w_rc); loop fetch w_rc into w_empname; exit when w_rc%notfound; dbms_output.put_line(name || w_empname); end loop; close w_rc; end; /如果屏幕按行输出了 emp_no 为 0001 的员工姓名说明 ref cursor 的返回逻辑是通的。如果一行都没有把 display 的第一个参数换成 null 再跑一次走 open p_rc for select emp_name from student 这条全量分支两条分支都验过才能确定问题是在动态 SQL 绑定上还是在数据本身。验证通过之后把 user_errors 的输出、两次匿名块的执行结果、以及最终的包声明和包体代码一起贴回 Codex让它做一次反向复核重点看绑定变量和游标关闭这两处是否还有隐患。五、本篇常见错排查按报错文本对照可以覆盖大部分现场第一类PLS-00201: identifier PKG_TEST.MYRCTYPE must be declared。说明包声明没编译成功或者当前会话看到的还是旧版本对象。先查 user_objects 的 status再查 user_errors别急着改匿名块。第二类PLS-00323: subprogram or cursor DISPLAY is declared in a package specification and must be defined in the package body。这是包体和包声明签名不一致的典型报错。逐字比对 p_empno 的参数名、char 类型、p_rc 的 out 模式与 myrctype 类型尤其注意包体里是否多写了默认值。第三类ORA-01008: not all variables bound。动态 SQL 里有 :w_empno但 using 后面的参数个数对不上或者某个分支忘了加 using。检查 open p_rc for v_sql using p_empno 这一行是否只在 else 分支里if 分支用的是静态 SQL 不需要 using。第四类ORA-00904: invalid identifier。多数是列表或表名写错或者当前用户没有 student 表的查询权限。用 desc student 确认列名是 emp_name、emp_no 再继续。第五类匿名块执行成功但一行都不打印。先确认 set serveroutput on 是否执行过再确认 exit when w_rc%notfound 的位置——它必须紧跟在 fetch 之后判断在打印之前否则容易出现多一行空值或漏掉数据。另外注意本文示例在循环后补了 close w_rc显式关闭游标是好习惯虽然会话结束也会释放。第六类Codex 报 401 或 404。401 通常是 Key 没放进环境变量或者变量名与 config.toml 里 env_key 写的不一致404 多半是 base_url 写成了 https://taotoken.net/api/v1或者把 UTM 参数一起粘了进去。把 base_url 恢复成 https://taotoken.net/api 即可。第七类改了代码但报错没变。Oracle 的包是有状态的包体重新编译后当前会话可能还持有旧的包状态。执行 alter session 或重新登录一次让会话重新加载包再跑一次验证。六、把 Key、Base URL 与文档一次配齐本篇涉及的动作可以归结成两张清单。一张是接入清单TaoToken 官网注册、创建 API Key、在 Codex 的 config.toml 里用 [model_providers.taotoken] 配好 base_url 为 https://taotoken.net/api、env_key 指向环境变量、model 填控制台给出的模型 ID。Key 管理页面在 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys 如果接入过程中对 base_url、wire_api、环境变量名有疑问接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc 两处对照看基本能把配置问题排掉。想先确认 Key 与模型是否真的可用可以到模型对话页发一条最短请求验证https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentchat 。另一张是代码清单pkg_test 的包声明、包体、匿名块三段必须同源同签名动态 SQL 里的 :w_empno 与 using p_empno 必须一一对应w_rc 的类型必须写成 pkg_test.myrctype验证时以 SQL*Plus 里 display(0001, w_rc) 的实际输出为准而不是以模型说“没问题”为准。如果你打算长期用 Codex 做这类存储过程重构、包体一致性核对甚至批量改 SQL 的工作可以了解一下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan 把 Key、Base URL 和日常编码链路固定下来省去每次重新配环境的来回。
返回列表