1. 为什么要在本地 AI 编码工具里折腾 MySQL 游标
MySQL 存储过程里的游标,是那种「平时用不上,一用就卡壳」的东西。它适合逐行处理结果集的场景,比如把一批用户 ID 拼成字符串、按行做数据清洗、或者给每行补一个计算字段。语法本身不复杂,但真正落地时,很多人会卡在三个地方:输出参数没初始化导致返回 null、delimiter和;冲突、repeat ... until done的终止条件写反。
我这次想聊的不只是游标本身,而是把它放进一个更顺手的工程流里:用本地 AI 编码工具(比如支持settings.json配置的编辑器插件)来写和调 SQL,同时通过 TaoToken 的统一 Key 和 API 通道,把模型调用收敛到一个入口。这样你写游标示例、让模型帮你解释报错、生成测试数据,都不用到处配 Key。
TaoToken 在这里的角色是「统一通道」:一个 Key 走模型对话、代码补全、Agent 调用。官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end ,API 入口是 https://taotoken.net/api 。下面我会先给settings.json的配置骨架,再给一份能直接跑的游标示例,最后给最小验证动作和排错清单。适合刚接触存储过程、又想顺手把 AI 编码工具配好的同学。
2. TaoToken 前置:Key 与 settings.json 骨架
在写游标之前,先把工具链配好。本地 AI 编码工具通常读一个settings.json,里面放模型提供方的baseURL、apiKey、模型名。用 TaoToken 的好处是:你只维护一个 Key,换模型只改model字段,不用动 Key。
先去控制台拿 Key,入口是 https://taotoken.net/console 。拿到之后,settings.json的骨架大概长这样(字段名按你用的插件微调,核心是baseURL指向 TaoToken 的 API 地址):
{ "provider": "openai-compatible", "baseURL": "https://taotoken.net/api", "apiKey": "sk-你的TaoTokenKey", "model": "claude-sonnet-4-20250514", "maxTokens": 4096, "temperature": 0.2, "timeout": 60000 }几个参数说明一下。baseURL用https://taotoken.net/api,不要带多余路径;temperature调低到 0.2,是因为写 SQL 和解释报错时你要的是稳定输出,不是发散创意;timeout给到 60 秒,长一点的存储过程解释不容易被截断。
注意:
apiKey不要提交到 Git。建议放在环境变量里,settings.json里写"apiKey": "${TAOTOKEN_API_KEY}",由工具在运行时注入。
如果你用的是 Claude Code 这类偏 Agent 的编码工具,配置入口和普通补全插件不太一样,可以参考 https://taotoken.net/doc 里的接入说明,或者直接看 https://taotoken.net/claude-code-anthropic 的对接方式。Key 的管理统一在 https://taotoken.net/api-keys 。
配好之后,先别急着写游标,用一次模型对话验证通道是否通:打开 https://taotoken.net/model-chat ,发一句「用一句话解释 MySQL 游标的作用」。能正常返回,说明 Key 和通道没问题,再回到编辑器里干活。
3. 可复制配置:游标示例与 settings.json 联动
现在进入正题。下面这份存储过程,功能是把test.user表里的id逐行取出,拼成一个字符串,通过输出参数返回。它覆盖了游标最关键的几个点:声明、CONTINUE HANDLER、repeat ... until、输出参数初始化。
drop procedure if exists cursor_user; delimiter // create procedure cursor_user(out result varchar(2000)) begin declare a varchar(20); declare done int default 0; declare cur cursor for select id from test.`user`; declare continue handler for not found set done = 1; set result = ''; open cur; repeat fetch cur into a; if done = 0 then set result = concat(a, ',', result); end if; until done end repeat; close cur; end; // delimiter ;这里有几个容易踩的点,我逐个说。
第一,declare done int default 0;一定要给默认值。很多人写declare done int;,结果done是 null,until done永远不成立,游标死循环。excerpt 里也提到输出参数要初始化,其实内部变量同理。
第二,declare continue handler for not found set done = 1;必须放在游标声明之后。顺序错了会报语法错误。
第三,fetch到最后一行之后,会触发not found,此时done变 1,但a里是上一行的旧值或 null。所以我在repeat里加了if done = 0 then判断,避免把脏数据拼进去。这是很多人结果多一个逗号或 null 的原因。
第四,delimiter //和结尾的delimiter ;是给客户端用的,不是 SQL 语法。少了它,MySQL 会在第一个;处截断存储过程定义。
调用和验证:
set @a = 'hi'; call cursor_user(@a); select @a;set @a = 'hi'是给输出参数一个初始值。虽然存储过程内部会set result = ''覆盖它,但养成初始化习惯没坏处。执行后select @a应该看到类似3,2,1,的拼接结果(取决于你表里的数据)。
如果你想让模型帮你检查这段 SQL,可以把代码贴到模型对话里,让它指出潜在问题。通道已经配好,直接问就行。
4. 验证请求:连接、调用、结果校验
配置和代码都有了,接下来做最小验证。分三步:连接、调用、校验。
连接层面,确认你的 MySQL 客户端能连上目标库,并且有创建存储过程的权限。执行select current_user();和show databases;确认环境。
调用层面,按上面的call cursor_user(@a);执行。如果报PROCEDURE test.cursor_user does not exist,说明创建时库选错了,用use test;切过去再建。
结果校验层面,select @a;看输出。预期是一个逗号拼接的字符串。如果结果是 null,检查set result = '';是否在open cur;之前执行;如果结果里出现 null 字样,检查if done = 0判断是否漏了;如果结果顺序和你预期相反,那是concat(a, ',', result)的拼接顺序问题,改成concat(result, ',', a)即可。
再补一个更直观的验证:建一张小表,插三行数据,跑一遍游标,看输出是否和手算一致。
create table if not exists test.user ( id int primary key, name varchar(20) ); insert into test.user values (1,'a'),(2,'b'),(3,'c');然后重新call cursor_user(@a); select @a;,预期得到3,2,1,。这个「手算 vs 实际」的对比,是最快的校验方式。
如果你在编辑器里让模型生成测试数据,记得把表结构一起贴给它,不然它可能编出不存在的字段。模型对话入口还是 https://taotoken.net/model-chat 。
5. 本篇常见错排查
下面这些报错,基本覆盖了游标落地的 90% 问题。
ERROR 1064 (42000)语法错误:多半是delimiter没设,或者declare顺序不对。记住顺序是「变量 → 游标 → handler」。
ERROR 1329 (02000) No data:fetch时结果集为空。检查select语句是否真的返回了行,以及open cur是否在repeat之前。
输出参数为 null:set result = ''没执行,或者call时没传参。输出参数虽然会被内部覆盖,但call时必须给一个占位变量。
死循环:done没默认值,或者until done写成了until done = 0。until后面跟的是「条件为真时结束」,所以until done表示done为 1 时结束。
结果多一个逗号:拼接逻辑没处理最后一行。用if done = 0包住set语句,或者改用group_concat替代游标(如果只是拼接,group_concat更简单)。
模型返回的 SQL 跑不通:先确认settings.json里的model字段是你想要的模型,再确认baseURL没写错。通道问题看 https://taotoken.net/doc ,Key 问题看 https://taotoken.net/api-keys 。
提示:调试游标时,可以在
repeat里临时加select result;看每轮拼接结果,定位到具体哪一行出问题,调完再删掉。
6. 把游标和 AI 编码流串起来
游标本身不难,难的是「写完能跑、跑错能查」。把 TaoToken 的统一 Key 接进settings.json之后,你写 SQL、问报错、生成测试数据都在一个通道里完成,不用在多个 Key 之间切换。
如果你只是偶尔写写存储过程,用模型对话就够了,入口在 https://taotoken.net/model-chat 。如果你长期在编辑器里做数据库相关的编码和 Agent 任务,建议看一下 Coding Plan,入口是 https://taotoken.net/coding-plan ,它更适合高频、长会话的场景。接入文档和参数细节都在 https://taotoken.net/doc ,Key 管理在 https://taotoken.net/api-keys 。
最后留一个我常用的习惯:每次写完游标,先在小表上跑一遍,确认输出和手算一致,再放到生产表上。这一步花不了一分钟,但能省掉很多「结果不对又不知道哪错」的时间。