Claude Code 乱猜字段名?我给它写了一个"数据库查询约束 Skill"

5 阅读9分钟

38岁保险后端程序员,用 Claude Code 写 SQL 被气到想砸键盘。这篇文章记录我怎么用一个 6 步流程 Skill,把 AI 从"瞎猜型选手"调教成"先查再问型选手"。


被 Claude Code 气到的一天

事情是这样的。

我在用 Claude Code 查一张保单表的数据,想看一下最近一个月的退保记录。我的指令很简单:

"查一下 policy_surrender 表最近 30 天的数据。"

Claude 很积极,唰唰唰生成了一段 SQL:

SELECT id, policy_no, created_at, surrender_amount, status 
FROM policy_surrender 
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY);

看起来挺对,对吧?

但执行直接报错。

created_at 字段不存在。这张表里记录创建时间的字段叫 create_time

我纠正它:"字段名是 create_time,不是 created_at

Claude 说"抱歉,我修改一下",然后重新生成:

SELECT id, policy_no, create_time, surrender_amount, status 
FROM policy_surrender 
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY);

这次字段名对了,但执行又报错。

surrender_amount 不存在。这张表存的是退保金额,但字段名是 refund_amount

我再次纠正。Claude 再次道歉,再次修改。然后 status 也不存在,实际字段叫 surrender_status

三个字段,它猜错了三个。

更要命的是,它完全没有"查一下表结构再写 SQL"的意识。它就像那种刚入职的实习生,听了需求就开始敲代码,完全不看数据库文档。


为什么 AI 会"瞎猜"?

这个问题不只是 Claude Code 有,Kimi、DeepSeek、GPT 都一样。

根本原因是:AI 的"常识"和数据库的"实际字段名"是两回事。

AI 见过无数的代码和数据库设计,它"知道"记录创建时间的字段通常叫 created_atcreate_timegmt_createcreated_date…… 所以当它看到"查一张表"的指令时,它会从自己的经验库里选一个最"常见"的字段名。

问题是,你的数据库字段名不一定按"常见"来命名。

比如保险行业的系统,很多字段命名有自己的历史包袱:

  • 有的字段叫 create_time(标准中文拼音风)
  • 有的叫 crt_tm(缩写风)
  • 有的叫 createdAt(驼峰风)
  • 甚至有的叫 c_time(极简风)

AI 猜中的概率,大概是 1/4 到 1/6。而在一个复杂查询里涉及 5-10 个字段,它全猜对的概率……你自己算。

更可怕的是,AI 不会告诉你"我在猜" 。它生成 SQL 的时候语气极其自信,就像真的查过表结构一样。你只有执行报错后才知道它在瞎蒙。


我的解法:给 Claude 写了一个 6 步 Skill

被反复折磨后,我决定不再每次都纠正它。我给它写了一个数据库查询 Skill,把它变成一个"有规矩的实习生"。

这个 Skill 的核心思想很简单:在写任何 SQL 之前,必须先查表结构。 就像老程序员带新人时说的:"先别急着写代码,先看看表里有啥字段。"

6 步流程

用户查询需求 → 第1步:查表结构 → 第2步:查数据量 → 第3步:判断范围 → 第4步:生成SQL+检查索引 → 第5步:用户确认 → 第6步:执行并保存知识库

第1步:查表结构(最关键)

Claude 必须先执行:

DESCRIBE policy_surrender;
-- 或
SHOW COLUMNS FROM policy_surrender;
-- 或(PostgreSQL)
SELECT column_name, data_type, column_comment 
FROM information_schema.columns 
WHERE table_name = 'policy_surrender';

然后把结果展示给用户。不是偷偷摸摸看,是明明确确展示

第2步:查数据量

在生成 SQL 之前,先查这张表的数据量:

SELECT COUNT(*) FROM policy_surrender;

第3步:判断范围,防止慢查询

如果数据量超过 10 万(这个阈值自己定),必须暂停

Claude 要这样告诉用户:

"这张表有 120 万条数据,直接查全表可能会很慢。建议你先加时间范围或其他条件,缩小查询范围。你确定要全量查询吗?"

不是直接执行,是先问

第4步:生成 SQL,并检查索引

Claude 根据表结构生成 SQL,然后自己检查 WHERE 条件是否命中索引

EXPLAIN SELECT * FROM policy_surrender WHERE create_time >= '2025-05-01';

如果 EXPLAIN 显示 type 是 ALL(全表扫描),Claude 必须警告用户:

"这个查询条件没有命中索引,可能会扫描全表。建议添加索引或缩小范围。"

第5步:用户确认

Claude 把生成的 SQL 展示给用户,等用户确认后再执行。不是自作主张点运行。

第6步:保存知识库

查询完成后,Claude 把这张表的表结构、字段含义、数据量、索引信息,保存到项目知识库。

下次用户再查这张表,Claude 可以直接读取知识库,不用再执行 DESCRIBE


Skill 写成什么样?

Claude Code 支持 project-specific 的 Skill(在 .claude/skills/ 目录下)。我的 Skill 文件长这样:

# 数据库查询 Skill## 约束规则
​
当用户要求查询数据库时,必须严格遵守以下流程:
​
### 1. 查表结构
- 执行 `DESCRIBE {table_name}``SHOW COLUMNS FROM {table_name}`
- 将结果展示给用户
- 不准猜测字段名,必须基于实际表结构
​
### 2. 查数据量
- 执行 `SELECT COUNT(*) FROM {table_name}`
- 如果数据量 > 100000,暂停执行,提示用户缩小范围
​
### 3. 判断范围
- 询问用户是否需要加 WHERE 条件
- 提供时间范围、ID 范围等建议
​
### 4. 生成 SQL + 检查索引
- 根据表结构生成 SQL
- 执行 `EXPLAIN` 检查索引命中情况
- 如果全表扫描,警告用户
​
### 5. 用户确认
- 展示 SQL,等待用户确认
- 未经确认不准执行
​
### 6. 保存知识库
- 将表结构信息保存到 `.claude/knowledge/db/{table_name}.md`
- 格式:字段名 | 类型 | 含义 | 索引
- 下次查询同一表时,优先读取知识库
​
## 禁止行为- 禁止猜测字段名
- 禁止不查表结构直接写 SQL
- 禁止不检查索引就执行大数据量查询
- 禁止未经用户确认执行 SQL
​
## 示例
​
用户:查一下 policy_surrender 表最近 30 天的数据
​
正确流程:
1. DESCRIBE policy_surrender → 展示字段
2. SELECT COUNT(*) → 判断数据量
3. 询问用户:是否需要加时间范围?建议按 create_time 查询
4. 生成 SQL:SELECT * FROM policy_surrender WHERE create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
5. EXPLAIN 检查索引
6. 展示 SQL,等待确认
7. 执行并保存知识库

实际效果如何?

Skill 上线后,Claude 的行为明显变了。

以前:

我:查一下 policy_surrender 表最近 30 天的数据
Claude:(直接生成 SQL3 个字段名全猜错)

现在:

我:查一下 policy_surrender 表最近 30 天的数据
Claude:我先查一下这张表的表结构。
      (执行 DESCRIBE,展示结果)
      这张表有 120 万条数据,建议加时间范围。你想按 create_time 查最近 30 天吗?
      (我确认后,生成 SQL,EXPLAIN 检查索引,展示给我看)
      这是 SQL,确认执行吗?
      (我确认后,执行)
      结果已保存到知识库,下次查这张表不用重复查结构。

不只是字段名不再猜错,更大的好处是:

  1. 慢查询被拦截了:有几次我差点执行全表扫描,Claude 提醒后我加了索引条件
  2. 知识库积累了:项目里 30 多张核心表的结构都被记录下来了,新同事问"这个字段什么意思"直接查知识库
  3. 我不再需要纠正它:它自己知道规矩,我省了很多口舌

当然,偶尔还是会遇到复杂场景需要人工干预。比如字段名特别模糊、中英文混杂、或者业务含义和字面意思差很远的时候,Claude 看了表结构还是可能理解歪。这时候我就直接告诉它正确答案,然后让它更新知识库——"人工干预→积累知识库→下次不用重复犯错",这个闭环跑起来后,越来越顺手。


其他 AI 工具也能用吗?

这个 Skill 本质上是一套约束规则,不是 Claude 特有的。

我后来把它改成了 Prompt 模板,在 Kimi、DeepSeek 上也能用:

你是一个数据库查询助手。当用户要求查询数据库时,必须按以下步骤执行:
​
1. 先执行 DESCRIBE {table_name},展示表结构
2. 执行 SELECT COUNT(*) FROM {table_name},判断数据量
3. 数据量超过10万时,提示用户缩小范围
4. 根据表结构生成SQL,执行EXPLAIN检查索引
5. 展示SQL,等待用户确认
6. 执行并保存表结构信息
​
禁止猜测字段名。禁止未经确认执行SQL

效果类似,但不如 Claude Code 的 Skill 那么"自动化"——因为 Kimi 和 DeepSeek 没有直接执行 SQL 的能力,需要你手动复制粘贴。但约束规则本身是有用的,至少它不会乱猜字段了。

我只在 Claude Code 上深度用这个 Skill,因为它能即时反馈、直接执行 SQL、还能自动优化 Skill 本身。其他工具我主要用来生成思路和初稿。


写在最后

这件事给我最大的启发是:用 AI 不是"给它自由",而是"给它规矩"。

AI 的创造力是双刃剑。它敢猜、敢试、敢犯错,但数据库查询这个场景,"敢猜"就是灾难。一个好的 Skill 不是限制 AI,而是帮它建立在这个场景下的正确工作习惯

就像带实习生一样:你不在旁边盯着的时候,它会不会老老实实先看文档再写代码?不会的,除非你反复训练,直到它养成肌肉记忆。

Claude Code 的 Skill 机制,就是给 AI 建肌肉记忆的工具。

如果你也被 AI 乱猜字段名气到过,建议试试这个 6 步流程。花 10 分钟写一个 Skill,以后省下的纠正时间远不止 10 分钟。


你有过被 AI "瞎猜"气到的经历吗?欢迎在评论区分享。如果你有更好的约束方法,也欢迎交流。38 岁程序员,还在学习怎么和 AI 相处。