ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【Oracle数据库】实验-游标cursor:从显式游标到游标FOR循环的完整实验手册(TaoToken 辅助排查连接报错)

2026/10/4 19:48:01 拓冰建站 浏览量
【Oracle数据库】实验-游标cursor:从显式游标到游标FOR循环的完整实验手册(TaoToken 辅助排查连接报错) 1. 从一次实验课翻车说起Oracle 游标到底解决什么问题如果你正在上 Oracle 数据库实验课看到cursor、open、fetch、%rowcount这些词就头大这篇就是写给你的。Oracle 游标cursor本质上是 PL/SQL 里用来逐行处理查询结果集的一个指针它让你能把select出来的多行数据一行一行拿出来做判断、计算、更新。适合谁适合正在做数据库实验、准备课程设计、或者第一次接触 PL/SQL 存储过程的人。我见过太多同学在实验课上卡住不是因为游标语法难而是因为环境没连上、dbms_output没开、或者scott用户被锁了结果代码明明抄对了却一直报错。这篇手册会先把游标四步走讲透再给参数化游标、游标 FOR 循环、for update游标的完整可粘贴脚本最后用 TaoToken 统一 Key 通道帮你排查 ORA-01031、连接失败这类环境问题。你不需要装一堆客户端SQL*Plus 或 SQL Developer 都能跑。先说清楚游标的核心价值普通select是一次性把结果集返回给客户端而游标是在服务端维护一个结果集指针你可以控制每次取几行、取到哪一行、什么时候停。这在做批量更新、逐行校验、统计汇总时特别有用。实验里常见的「统计各部门平均工资」「按部门号动态查询员工」「工资低于 1000 调到 1500」都是游标的典型场景。游标分两类显式游标和隐式游标。显式游标是你自己declare cursor声明、自己open/fetch/close的隐式游标是 Oracle 为每条 DML 语句自动开的你用SQL%ROWCOUNT、SQL%FOUND这些属性去读它的状态。实验里两种都会考下面逐个拆。2. TaoToken 前置准备统一 Key 通道与连接报错排查做游标实验之前先把连接问题解决掉否则你会在ORA-01031: insufficient privileges或者ORA-12541: TNS:no listener上耗掉半节课。我的做法是用 TaoToken 做一个统一的 Key 通道把模型对话、编码辅助、接口调试都走同一个入口这样排查连接类报错时不用在多个平台之间来回切换。TaoToken 官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。它的作用是给你一个统一的 Key 和 Base URL让你在写 PL/SQL 实验报告、调试连接脚本、或者让 AI 帮你解释报错时有一个稳定的通道。注意它不是数据库客户端也不替代 SQL Developer它只是帮你把「查文档、问报错、生成脚本」这些动作串起来。具体怎么用第一步去控制台创建一个 API Key地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建完把 Key 复制下来后面配置里要用。第二步如果你要验证模型通道是否通可以用模型对话页面 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 发一条测试消息。第三步如果你打算长期做编码和 Agent 类任务可以看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。这里要强调一个排查思路当你遇到ORA-01031时先别急着改游标代码先确认三件事——数据库用户有没有create session权限、scott用户是不是被锁、dbms_output有没有开。这三件事用 SQL*Plus 几条命令就能查。而如果你是在用 AI 辅助生成游标脚本时遇到接口报错比如401、local proxy failed、reading choices这类那就要检查你的 Base URL 和 Key 是否配对。TaoToken 的接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有完整的 Base URL、Key、Model ID 三件套说明。我实测下来把 Key 通道统一之后最大的好处是排查报错时不用猜「到底是数据库的问题还是工具的问题」。你可以在同一个通道里先验证模型能不能正常返回再去跑游标脚本这样问题定位快很多。API Keys 管理页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 建议把实验用的 Key 单独建一个方便轮换。3. 可复制配置显式游标四步与参数化游标完整脚本这一节给你可以直接粘贴运行的脚本。先建实验表再跑游标。我用xs学生表和scott.emp表做例子你可以按自己实验指导书替换表名。先建xs表并插数据-- 建表 create table xs ( xh varchar2(10), xm varchar2(20), xb varchar2(4) ); -- 插入测试数据 insert into xs values (001, 张三, 男); insert into xs values (002, 李四, 女); insert into xs values (003, 王五, 男); commit;显式游标的标准四步是声明declare、打开open、提取fetch、关闭close。下面是最小可运行版本set serveroutput on; declare cursor c_1 is select xm from xs; v_1 xs.xm%type; begin open c_1; fetch c_1 into v_1; dbms_output.put_line(v_1); close c_1; end; /注意set serveroutput on;必须加否则dbms_output.put_line的输出你看不到。这是实验课最常见的「代码没错但没输出」原因。用%rowtype一次取整行declare cursor c_1 is select * from xs; v_1 xs%rowtype; begin open c_1; fetch c_1 into v_1; dbms_output.put_line(v_1.xh || || v_1.xm); close c_1; end; /带参数的游标参数在open时传入declare cursor c_1(v_xb xs.xb%type) is select * from xs where xb v_xb; v_1 xs%rowtype; begin open c_1(男); fetch c_1 into v_1; dbms_output.put_line(v_1.xh || || v_1.xm); close c_1; end; /多表查询游标用%rowtype承接declare cursor c_4 is select empno, ename, emp.deptno, dname from scott.emp, scott.dept where emp.deptno dept.deptno; v_4 c_4%rowtype; begin open c_4; fetch c_4 into v_4; dbms_output.put_line(v_4.empno || || v_4.ename || || v_4.deptno || || v_4.dname); close c_4; end; /用%rowcount显示当前取到第几行declare cursor c_1 is select xm from xs; v_1 xs.xm%type; begin open c_1; fetch c_1 into v_1; dbms_output.put_line(v_1 || || c_1%rowcount); close c_1; end; /如果你要用 AI 辅助生成这些脚本可以在 TaoToken 的模型对话里贴报错信息让它帮你定位。配置时记住三件套Base URL 用https://taotoken.net/apiKey 用你在控制台创建的那串Model ID 按文档里写的填。这三样缺一不可配错了就会报401或reading choices类错误。4. 验证请求与成功结果循环、FOR 循环与 for update 游标游标真正好用的地方在于循环处理多行。先看用loopexit when %notfound的写法这是实验里最常考的declare v_deptno scott.emp.deptno%type; cursor c_emp is select * from scott.emp where scott.emp.deptno v_deptno; v_emp c_emp%rowtype; begin v_deptno : x; open c_emp; loop fetch c_emp into v_emp; exit when c_emp%notfound; dbms_output.put_line(v_emp.empno || || v_emp.ename || || v_emp.deptno || || v_emp.sal); end loop; close c_emp; end; /运行时会提示你输入x的值输入10就能看到 10 号部门的员工。这里x是 SQL*Plus 的替换变量SQL Developer 里也能用。统计各部门平均工资用简单循环declare cursor c_dept is select deptno, avg(sal) avgsal from scott.emp group by deptno; v_dept c_dept%rowtype; begin open c_dept; loop fetch c_dept into v_dept; exit when c_dept%notfound; dbms_output.put_line(v_dept.deptno || || v_dept.avgsal); end loop; close c_dept; end; /用while循环改写注意fetch要写两次一次在循环前一次在循环体末尾declare cursor c_dept is select deptno, avg(sal) avgsal from scott.emp group by deptno; v_dept c_dept%rowtype; begin open c_dept; fetch c_dept into v_dept; while c_dept%found loop dbms_output.put_line(v_dept.deptno || || v_dept.avgsal); fetch c_dept into v_dept; end loop; close c_dept; end; /最简洁的是游标 FOR 循环不用手动open/fetch/closeOracle 自动帮你做declare cursor c_dept is select deptno, avg(sal) avgsal from scott.emp group by deptno; begin for v_dept in c_dept loop dbms_output.put_line(v_dept.deptno || || v_dept.avgsal); end loop; end; /for update游标用于边遍历边更新配合where current of定位当前行declare cursor c_emp is select * from scott.emp for update; v_zl number; begin for v_emp in c_emp loop case v_emp.deptno when 10 then v_zl : 100; when 20 then v_zl : 150; when 30 then v_zl : 200; else v_zl : 250; end case; update scott.emp set sal sal v_zl where current of c_emp; end loop; commit; end; /注意原实验代码里case三个分支都写成了when 10那是笔误正确写法是when 10 / when 20 / when 30。这个坑我在批改实验报告时见过好几次。再看一个带条件判断的工资调整declare cursor c_1 is select empno, sal from scott.emp for update of sal; v_sal scott.emp.sal%type; begin for v_1 in c_1 loop if v_1.sal 1000 then v_sal : 1500; else v_sal : v_1.sal * 1.5; if v_sal 10000 then v_sal : 10000; end if; end if; update scott.emp set sal v_sal where current of c_1; end loop; commit; end; /成功运行的标志是set serveroutput on之后能看到逐行输出for update脚本执行完commit后查表数据确实变了。如果没输出先检查serveroutput如果报ORA-01031检查权限如果报ORA-00942检查表名和 schema 前缀。5. 本篇常见报错排查ORA-01031、连接失败与游标属性误用实验里最容易卡住的不是游标逻辑而是环境和属性误用。下面按真实报错逐个说。ORA-01031: insufficient privileges通常出现在你试图访问scott.emp但没有权限或者scott用户被锁。解决动作用 DBA 账号执行alter user scott account unlock;和grant connect, resource to scott;。如果你用的是自己的用户确认有create session和select权限。ORA-12541: TNS:no listener或连接失败先确认监听服务起了没lsnrctl status看一眼。如果是用 AI 工具辅助时遇到local proxy failed那多半是 Base URL 配错了。TaoToken 的 Base URL 是https://taotoken.net/api不要多加路径也不要漏掉/api。Key 和 Model ID 要跟文档一致三件套配齐。ORA-06550或PLS-00201一般是变量类型声明不对比如v_1 xs.xm%type里表名或列名拼错。检查%type前面的表列是否存在。ORA-01001: invalid cursor是游标没open就fetch或者close之后又fetch。显式游标必须严格按 open→fetch→close 顺序。%rowcount返回 0 或不对是因为你在fetch之前就读了它。%rowcount表示当前已经取到的行数必须在fetch之后读。%notfound和%found用反了会导致循环多跑一次或少跑一次。记住exit when c_emp%notfound是取不到数据时退出while c_dept%found是有数据时继续。dbms_output没输出99% 是忘了set serveroutput on;。在 SQL Developer 里还要确认「DBMS Output」面板已经启用。如果你在配置 AI 辅助通道时遇到401去 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 确认 Key 没过期。遇到reading choices类报错检查 Model ID 是否填对。接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里有完整的参数对照表。6. 把游标实验跑通之后统一通道与长期编码习惯游标实验跑通只是第一步。真正让你省时间的是把「写脚本、查报错、验证结果」这条链路固定下来。我的习惯是数据库连接用 SQL Developer脚本生成和报错解释走 TaoToken 的统一 Key 通道这样不用在多个工具之间复制粘贴。如果你后面还要做存储过程、触发器、包这些 PL/SQL 内容建议把 Coding Plan 用起来地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它适合长期编码和 Agent 类任务比每次单独配 Key 省事。模型对话入口在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 验证模型是否正常返回就用它。最后给你一个实用技巧把常用的游标模板存成一个.sql文件每次实验改表名和条件就行。for update游标记得加commit否则数据不落库。%rowtype和%type能少写很多类型声明但表结构变了要重新编译。游标 FOR 循环最省代码但如果你需要在循环中间做复杂控制还是用显式游标更灵活。实验报告里如果要求写「游标四步」就按 declare→open→fetch→close 写要求「隐式游标属性」就写SQL%ROWCOUNT、SQL%FOUND、SQL%NOTFOUND要求「参数化游标」就在cursor声明里加参数open时传值。这些点覆盖了绝大多数 Oracle 游标实验的评分项。