使用示例(通过Skill接入第三方Agent)
工作流程
环境准备 → SQL分析与转换 → 残余SQL AI适配 → 目标库验证与规则沉淀 → Patch与报告生成
工作目录
Skill使用专用工作目录存放中间产物,默认为<项目路径>/.devkit-sql-migration/,可通过“--work-dir”自定义位置。
<WORK_DIR>/
├── source-code/
│ ├── a/ # 基准副本(不修改)
│ └── b/ # 工作副本(AI 修改后)
├── reports/ # 迁移报告与输出产物
├── downloads/ # DevKit 工具包、JDK 下载包(重复迁移时保留)
├── logs/ # 日志
├── sql-analysis/ # DevKit SQL Analysis 工具(重复迁移时保留)
└── devkit-sql-migration-cache/ # 规则库(重复迁移时保留)
└── rulers_<SOURCE>_to_<TARGET>.md
操作步骤
以使用OpenCode将Oracle数据库的SQL迁移至MySQL数据库为例。
使用Skill进行迁移的过程中,需用户通过本地配置文件或在Agent交互中提供数据库或服务器的用户名和密码连接源数据库或源服务器,可能存在一定安全风险,为保障用户数据安全,使用后请及时删除配置文件中的密码。
迁移过程中不对用户名和密码做存储操作,仅作为迁移流程中的一次性使用。
- 已在OpenCode中配置好Skill。
SQL迁移的Skill可在开源仓获取,配置方式可参考为第三方Agent配置Skill。
- 在对话框中输入迁移意图。
请帮我将/home/My-Blog-master项目中的SQL从Oracle迁移到MySQL
- 选择SQL迁移的验证方式。
选择第一个。
项目已确认:/home/My-Blog-master( MyBatis 项目,SQL 内嵌在 Mapper XML),迁移方向 Oracle → MySQL。 我已检查动态验证配置 assets/db-connection.json: - 源库( Oracle): flag=false( 未启用) - 目标库( MySQL): flag=true( 已配置连接) 按流程需确认动态验证方式: → Asked 1 question Build · deepseek-v4-flash 请选择本次 SQL 迁移的动态验证启用方式(源库 Oracle 当前未启用,目标库 MySQL 已启用): 1. 启用,需配置源库(Recommended) 引导你编辑 assets/db-connection.json,将 source_db_conn.flag 设为 true 并填写 Oracle 连接信息, 配好后开始迁移 2. 静态分析 不启用动态验证,仅进行静态 SQL 分析与转换,直接开始迁移 3. 已启用,直接开始 你认为当前配置已就绪(注意源库 flag 当前为 false),跳过配置直接开始 4. Type your own answer
- 查看迁移结果。
迁移完成后将输出迁移结果和迁移产物文件位置。
迁移已完成。状态 COMPLETED WITH ACTIONS( 存在 5 项需人工复核的 SQL)。 迁移结果 项目 : /home/My-Blog-master( Oracle → MySQL, 路线 A: DevKit 转 换 + AI 残余处理) 验证模式:源库 Oracle 动态验证未启用;目标库 MySQL 动态验证已启用( EXPLAIN) 统 计( 64 个工作项): ┌───────────────────────────┬─────────────────────────────────┐ │分类 │数量 │ │───────────────────────────│─────────────────────────────────│ │兼容(无需改动) │57 │ │───────────────────────────│─────────────────────────────────│ │AI 转换(converted) │7 │ │───────────────────────────│─────────────────────────────────│ │需人工复核(manual-review) │5 │ │───────────────────────────│─────────────────────────────────│ │待确认 │0 │ └───────────────────────────│─────────────────────────────────┘ 已完成的转换( source_code.patch 已生成): - seq employee id.NEXTVAL - 字面量 1( BlogCategoryMapper) - SYS_GUID() - UUID()< BlogLinkMapper + 两个 Java 文件)的 - TO CHAR(SYSDATE, YYYY’) - DATE FORMAT(NOW(),'%Y’) - ORDER BY salary ASC - ORDER BY salary IS NULL ASC, salary ASC( 保持 0racle NULL 排序语义) - first name \|\| last name - CONCAT(first name, , last name) - Devkit 另转换了 USER-CURRENT USER()、 SYSTIMESTAMP-NOW(6)、 ALTER SESSION-USE 需人工复核的 5 项( manual review report.json) : getTotalCategories2、selectByPrimaryKey1/2/3、 main。这些 SQL 语法转换本身正确,但 EXPLAIN 失败( Table mysql.employees'/'EMP’ doesn’t exist 或 'NULL’语法错误)——因为涉及 employees/EMP 等示例表在目标库不存在,属于人工测试数据,建议确认这些测试 SQL 是否需保留。 产物位置: - Patch: /home/My-Blog-master/.devkit-sql-migration/reports/source_code.patch - 汇总:migration summary.csv, sql-migration-result.json - 人工复核: manual review report.json 规则沉淀: devkit-sql-migration-cache/rulers_Oracle to MySQL.md( 已沉淀 SYS_GUID-UUID 规则) 迁移已进入 WAITING_FOR_USER_DECISION 状态。 是否查看已有结果详情, 或重新迁移?
- 查看patch文件。可直接应用该patch文件,将patch文件中SQL相关的修改应用到源码文件中。
diff -ruN '--exclude=.devkit-sql-migration' '--exclude=.git' '--exclude=.svn' '--exclude=.hg' '--exclude=.*.log' '--exclude=*.json' '--exclude=*.patch' a/src/mai n/resources/mapper/BlogCategoryMapper.xml b/src/main/resources/mapper/BlogCategoryMapper.xml --- a/src/main/resources/mapper/BlogCategoryMapper.xml 2026-08-24 11:23:57.666970299 +0800 +++ b/src/main/resources/mapper/BlogCategoryMapper.xml 2026-08-24 11:28:08.84855858 +0800 @@ -29,11 +29,11 @@ </select> <select id="getTotalCategories1" parameterType="Map" resultType="int"> - select USER FROM DUAL; + select CURRENT_USER() FROM DUAL; </select> <select id="getTotalCategories2" parameterType="Map" resultType="int"> - INSERT INTO employees (employee_id, employee_name) VALUES (seq_employee_id.NEXTVAL, 'John Doe'); + INSERT INTO employees (employee_id, employee_name) VALUES (1, 'John Doe'); </select> diff -ruN '--exclude=.devkit-sql-migration' '--exclude=.git' '--exclude=.svn' '--exclude=.hg' '--exclude=*.log' '--exclude=*.json' '--exclude=*.patch' a/src/mai n/resources/mapper/BlogLinkMapper.xml b/src/main/resources/mapper/BlogLinkMapper.xml --- a/src/main/resources/mapper/BlogLinkMapper.xml 2026-08-24 11:23:57.666970299 +0800 +++ b/src/main/resources/mapper/BlogLinkMapper.xml 2026-08-24 11:30:24.309415141 +0800 @@ -24,15 +24,15 @@ <select id="selectByPrimaryKey1" parameterType="java.lang.Integer"> - SELECT * FROM employees ORDER BY salary ASC; + SELECT * FROM employees ORDER BY salary IS NULL ASC, salary ASC; </select> <select id="selectByPrimaryKey2" parameterType="java.lang.Integer"> - SELECT TO_CHAR(SYSDATE, 'YYYY'), id, name FROM #{tableName}; + SELECT DATE_FORMAT(NOW(), '%Y'), id, name FROM #{tableName}; </select> <select id="selectByPrimaryKey3" parameterType="java.lang.Integer"> - SELECT SYS_GUID(), id, name FROM #{table_name}; + SELECT UUID(), id, name FROM #{table_name}; </select>
输出产物
迁移完成后,将在$WORK_DIR/reports/下生成核心输出:
文件 |
说明 |
|---|---|
sql-migration-result.json |
最终迁移结果 |
source_code.patch |
最终合并Patch |
migration_summary.csv |
汇总报告 |
manual_review_report.json |
需人工介入SQL |
pending_confirm_sql.json |
待确认SQL |
转换规则沉淀在$WORK_DIR/devkit-sql-migration-cache/rulers_<SOURCE>_to_<TARGET>.md。其余文件(env_check_report.json、ai-workset.json、to_do-migrated_sql.json等)为中间过程产物,仅用于流程内部流转。
父主题: SQL迁移