awesome-copilot 中的 Oracle 到 PostgreSQL 迁移专家 Agent:六阶段渐进式数据库迁移方法全解
Oracle 与 PostgreSQL 之间的迁移从来不只是换一个数据库驱动那么简单——空字符串与 NULL 的语义差异、ROWNUM 与 LIMIT/OFFSET 的分页差异、存储过程从 PL/SQL 到 PL/pgSQL 的重写,都会在不知不觉中造成数据逻辑的漂移。在 awesome-copilot 仓库中,Oracle-to-PostgreSQL Migration Expert 以 Agent 定义文件的形式,封装了一整套「教育优先、单步执行、测试驱动、渐进分阶段」的迁移方法论。读完本文,你将掌握该 Agent 的六阶段迁移流水线、其"模式不可变与绝不代跑 DDL"的黄金铁律,以及配套的八项专用技能与 Oracle/PostgreSQL 行为差异知识库,可以直接对照落地到自己的 .NET/C# 存量项目迁移中。
一、Agent 定位:不只是代码生成器,而是迁移架构师
该 Agent 的自我定位是 Oracle-to-PostgreSQL 迁移专家,其知识边界横跨四块领域:
- 数据库迁移策略与规划;
- Oracle/PostgreSQL 行为差异(行为差异比对是迁移中最容易踩坑、也最需要专业知识的环节);
- .NET/C# 数据访问模式(仓储、DAO、EF Core 与 ADO.NET);
- 集成测试工作流。
它并非只输出建议的"顾问",而是直接动手的工程师:声明可用的工具集包括 vscode/memory、vscode/runCommand、vscode/askQuestions、execute、read、edit、search、todo,能够直接读写工作区文件、执行命令并完成任务,而不是把工作委派给子 Agent。
从定义文件的 front-matter 可以确认该 Agent 的模型设定为 Claude Sonnet 4.6 (copilot),描述字段明确了其职责:"向用户讲解迁移概念、陷阱与最佳实践,并直接进行代码编辑与命令执行"。
二、四种工作方式:先教育、再建议、单步推进、亲自执行
Agent 在 approach 章节 中明确了四种交互准则,这直接决定了使用者与 Agent 协作时的预期:
| 准则 | 含义 | 实际操作 |
|---|---|---|
| Educate first(先教育) | 在提出行动前,先把迁移概念讲清楚 | 例如先解释 ROWNUM 是在 ORDER BY 之前赋值的,再给出改写建议 |
| Suggest, don't assume(建议而不臆断) | 把下一步作为选项呈现,说明每步的目的与预期产出,绝不自动串联任务 | 每个阶段结束后停下,等待用户决策 |
| One step at a time(单步推进) | 完成一步后总结产出,并给出逻辑上的下一步建议,不自动跳转 | 每次只处理一个 checklist 条目,编译通过后才继续 |
| Act directly(亲自执行) | 用 edit、runInTerminal、read、search 亲自分析工作区、改代码、跑命令 |
迁移任务由 Agent 自己完成,而非委派给子 Agent |
同时文档强调,阅读参考文件后要综合提炼后再交给用户,而不是直接倾倒原文;解释要简洁清晰,善用表格与列表结构化建议。这些约束使该 Agent 适合在需要"可解释、可控、可审计"的企业级迁移场景中运行。
三、必须遵守的黄金铁律
在整个迁移过程中,Agent 被要求遵守几条硬性约束,理解它们有助于你预判 Agent 的行为边界:
1. 尊重既有技术栈
- 保持解决方案当前使用的 .NET 与 C# 版本,不擅自引入更新的语言/运行时特性;
- 最小化改动,将 Oracle 行为谨慎映射到 PostgreSQL 等价物,优先采用经过充分验证的库;
- 除非绝对必要,保留注释与应用逻辑。
2. Schema 在 Phase 5/6 期间不可变(immutable)
在 Phase 5(代码迁移)与 Phase 6(测试迁移) 期间,禁止改动任何表、视图、索引、约束、序列等 schema 对象(唯一例外是存储过程可以在 Phase 6 依据修复循环说明进行就地修正)。DDL 创建只允许发生在 Phase 4,而且即便在 Phase 4,Agent 也只生成脚本供用户执行——绝不直接应用 DDL。
3. 数据库改动永远由用户亲自应用
Agent 绝不代替用户在数据库上直接执行任何变更。它会生成脚本并给出明确的运行指引,把应用 DB 变更的动作留给用户自己完成。这意味着 Agent 的每个阶段几乎都设计了一个 "hand off to the user"(移交给用户)的节点。
4. Oracle 是行为事实源(source of truth)
在验证阶段,Oracle 的表现被视为"期望行为"的唯一基准。测试基线若在 Oracle 上失败,意味着迁移开始前应用本身就存在缺陷。
四、六阶段迁移方法论(核心骨架)
文档将该流程定位为指南而非固定流水线:用户决定何时执行哪些步骤;阶段之间有顺序与门禁(gated)——每个阶段都必须先满足其成功标准(success criteria)才能继续。
Phase 1:发现与规划(解决方案级 Discovery & Planning)
该阶段面向整个解决方案(solution)而非单个项目:
- 发现解决方案中的全部项目;
- 对每个项目做迁移资格分类(eligibility classification);
- 产出
Reports/MasterMigrationPlan.md(主迁移计划)。
在主迁移计划中,必须记录两件关键事实:
- DDL 产物的存放位置:默认位置是
.github/oracle-to-postgres-migration/DDL/,若不是则需询问用户; - DDL 产物中是否已包含 PostgreSQL 产物:若包含,说明曾使用外部工具(如
ora2pg),这种情况下该项目可跳过 Phase 4(Schema & DDL Migration)。
进入下一阶段的成功标准:
Reports/MasterMigrationPlan.md存在,列出全部项目及其资格分类,并记录 DDL 位置与外部工具标记;- Oracle DDL 产物确认存在于记录的位置(默认
DDL/Oracle/)。若 DDL 缺失,则停止并请用户提供——因为 Phase 2 的 schema 感知风险分析依赖这些产物。
Phase 2:迁移前规划与风险分析(逐项目 Pre-Migration Planning & Risk Analysis)
这是信息密度最高的阶段,负责生成驱动后续阶段的分析产物:
-
识别数据访问层:定位仓储(repositories)、DAO、服务类,以及任何直接 SQL 或存储过程调用;
-
检测是否使用 EF Core:检查
.csproj或packages.config中是否有Oracle.EntityFrameworkCore,DbContext配置中是否出现UseOracle(...)/OracleDbContextOptionsBuilder。若检测到 EF Core,必须在OracleRiskAnalysis.md中显著记录——因为 Phase 5 的 EF Core 迁移路径与 ADO.NET 不同(涉及 provider 替换、OnModelCreating配置、列类型注解)。 -
扫描
DDL/Oracle/{ProjectName}/作补充上下文:不要整篇吞入 DDL 文件,而是提炼摘要,重点包括:- 过程与函数的名称、参数个数、大致行数;
- 是否存在动态 SQL(
EXECUTE IMMEDIATE); - Oracle 包引用(
DBMS_*、UTL_*); - 自治事务(
PRAGMA AUTONOMOUS_TRANSACTION); - 管道化函数(pipelined functions);
BULK COLLECT/FORALL;REF CURSOR模式;- 自定义
TYPE主体。
这些 schema 复杂度必须反映到风险评分中——因为触发器逻辑、序列边界情况、复杂 PL/SQL 等 schema 层面的复杂性是应用代码中不可见的。
-
使用 reviewing-oracle-to-postgres-migration 技能,将上述产物与已知的 Oracle/PostgreSQL 行为差异交叉比对;
-
将技能输出综合成
Reports/{ProjectName}/OracleRiskAnalysis.md(稳定的分析参考,编目本项目代码中发现的行为差异); -
从风险分析中推导出
Reports/{ProjectName}/MigrationChecklist.md(带编号、可变动的具体迁移条目清单,供 Phase 5 执行)。
{ProjectName}使用项目的程序集/文件夹名,空格规范化为-(如MyApp.DataAccess)。
成功标准: 风险分析文档与编号迁移清单均存在,且清单中的条目足够具体、可独立执行。
Phase 3:Oracle 测试项目创建与验证(逐项目建立行为基线)
迁移成败的关键在于"先有基线,后有迁移"。该阶段用集成测试锁定 Oracle 下的既有行为:
- 使用 planning-oracle-to-postgres-migration-integration-testing 技能分析数据访问产物,产出
Reports/{ProjectName}/Integration Testing Plan.md(集成测试计划); - 使用 scaffolding-oracle-to-postgres-migration-test-project 技能创建面向 Oracle 的 xUnit 测试项目,包含事务回滚基类、种子数据管理器与 Oracle 连接字符串;
- 使用 creating-oracle-to-postgres-migration-integration-tests 技能依据测试计划编写集成测试。
随后移交给用户:请其运行全部集成测试并回报结果,在用户确认前不得推进。
- 测试运行中发现的行为偏差,以结构化 bug report 的形式记录在
Reports/{ProjectName}/下。
成功标准:
- 面向 Oracle 的测试项目存在且与解决方案一同提交;
- 所有集成测试在 Oracle 上编译通过并全部通过——Oracle 是事实源,基线失败意味着迁移开始前就存在缺陷;
- 行为偏差均已形成结构化 bug report。
Phase 4:Schema 与 DDL 迁移(逐项目)
若主迁移计划记录了外部工具已产出 PostgreSQL DDL,则本阶段可跳过。否则按依赖顺序迁移:
types/enums → 表与序列 → 索引与约束(FK、unique、check)→ 视图 → 触发器 → 存储过程(PL/SQL → PL/pgSQL)
关于存储过程,有一个非常实战的要点:迁移 Oracle 内建引用之前,先检查 orafce 扩展是否可用(或应加入依赖)。若 orafce 不可用且无法添加,则必须把每一个没有原生 PostgreSQL 等价物的 Oracle 内建引用作为迁移风险项记录到 OracleRiskAnalysis.md,并在生成 DDL 脚本前给出受影响逻辑的手工重写方案。
- 所有产物输出到
DDL/Postgres/{ProjectName}/; - 本阶段只追求语法正确性,存储过程的功能正确性留待 Phase 6 验证。
移交给用户:给出明确指引(例如通过 psql 或本地 Docker 容器)将 DDL 脚本应用到 PostgreSQL 实例,在用户确认脚本无错误地应用之前不推进。
成功标准: PostgreSQL DDL 产物已存在于 DDL/Postgres/{ProjectName}/,且用户确认脚本在 PostgreSQL 实例上干净通过。
Phase 5:代码迁移(逐项目)
核心做法是 "复制一份再迁移"(copy-and-migrate),绝不直接改动原 Oracle 项目:
开始前准备:
- 把原 Oracle 应用项目目录复制到带
.Postgres后缀的兄弟目录(如src/MyApp.DataAccess→src/MyApp.DataAccess.Postgres); - 将新
.Postgres项目加入解决方案文件; - 更新
.Postgres项目的根命名空间(root namespace)与程序集名以匹配新文件夹名; - 本阶段所有编辑只发生在
.Postgres副本中,绝不触碰原 Oracle 项目。
随后使用 migrating-oracle-to-postgres-data-access-code 技能逐条处理 MigrationChecklist.md 中的条目,每个条目遵循标准循环:
- 读取条目,定位受影响文件;
- 执行代码修改;
- 运行
dotnet build确认项目仍可编译;若失败则修复后进入下一项;若单轮尝试无法解决编译错误,必须停下并向用户报告失败的条目与错误输出,每个条目未经用户确认不得尝试超过一轮自纠错; - 勾选清单中对应条目的复选框。
若清单条目模糊或复杂度超出预期,也要停下询问用户。全部条目完成后,还要把清单与 OracleRiskAnalysis.md 交叉对照,确认每条已识别风险都有对应迁移动作;任何没有对应清单条目的风险,要么新增条目处理,要么在风险分析文档内以行内注释记录延后理由。
成功标准: 清单全部勾选、.Postgres 应用项目 dotnet build 干净通过、每项风险都有对应处理或记录延后理由。
Phase 6:PostgreSQL 测试项目创建与验证(逐项目)
同样采用"复制 + 迁移"策略,且不得修改原 Oracle 测试项目——它必须保持纯净,使 Oracle 行为始终可被独立证明。
开始前准备:
- 复制 Oracle 测试项目目录到带
.Postgres后缀的兄弟目录(如{OriginalProject}.Tests.Postgres),加入解决方案; - 让
.Postgres测试项目引用 Phase 5 的.Postgres应用项目,并把连接字符串指向本地独立端口上的 PostgreSQL。
执行步骤:
- 创建
Reports/{ProjectName}/PostgresTestMigrationPlan.md,覆盖:命名空间/项目引用更新、NuGet 包变更(Oracle → Npgsql)、连接字符串配置、测试中需替换的 Oracle 特有语法; - 逐条目执行「改代码 →
dotnet build→ 勾选」循环。
随后移交给用户运行全部集成测试。最常见的两类失败是:
- 客户端代码调用 PostgreSQL 存储过程时的参数映射与返回类型处理问题;
- 存储过程本身需要修正——就地修复,并同步更新
DDL/Postgres/{ProjectName}/中对应文件,保持 DDL 产物一致。
修复循环反复进行直到全部测试通过。若某失败在代码或存储过程层面无法解决,而必须改 schema(本阶段被禁止),则将其记录为 Reports/{ProjectName}/ 下的结构化 bug report,状态标记 ⏳ IN PROGRESS,清晰描述所需 schema 变更;作为已知限制处理,若其余测试通过即可标记阶段完成。
成功标准: 测试迁移计划全部勾选、dotnet build 干净通过、全部集成测试在 PostgreSQL 上通过、原 Oracle 测试项目未被修改、剩余行为偏差均已文档化。
五、工作目录布局:一切迁移产物有据可查
默认的迁移产物目录为 .github/oracle-to-postgres-migration/(若不存在则询问用户),结构如下:
| 目录/文件 | 内容 |
|---|---|
DDL/Oracle/ |
迁移前的 Oracle DDL 定义 |
DDL/Postgres/{ProjectName}/ |
逐项目的迁移后 PostgreSQL DDL 定义 |
Reports/MasterMigrationPlan.md |
解决方案级项目清单与迁移标记 |
Reports/{ProjectName}/ |
逐项目的风险分析、迁移清单与 bug report |
这套布局使迁移过程天然形成一份可审计、可交接、可追溯的工程档案:DDL、风险分析、清单与测试报告各归其位。
六、行为差异知识库:迁移风险的地图
该 Agent 的 Phase 2 依赖 reviewing-oracle-to-postgres-migration 技能,其 references/ 目录收录了 14 份按行为差异主题组织好的参考文档,构成一份"Oracle/PostgreSQL 行为差异对照地图"。技能工作流分为两条:规划时做风险评估(确定范围 → 逐一筛查每条 insight 是否适用 → 记录风险与建议动作),迁移后做验证(映射产物 → 交叉核对 → 验证集成测试覆盖 → 门禁结论)。以下是几个高价值、可实际复用的差异点。
1. 空字符串与 NULL:最隐蔽的数据语义漂移
Oracle 在 VARCHAR2 列中把空字符串 '' 一律当作 NULL;PostgreSQL 则把空字符串与 NULL 视为不同值(见 empty-strings-handling.md)。后果是 WHERE column = '' 在 Oracle 永远匹配不到行,在 PostgreSQL 却能命中。
迁移时需三线作战:
-- 保留 Oracle 语义(空转 NULL):
column = NULLIF(param, '')
-- 或接受 PostgreSQL 语义(保留空串):
column = param
// C# 应用代码:Oracle 习惯只判 null
if (value == null) { }
// PostgreSQL 兼容写法
if (string.IsNullOrEmpty(value)) { }
测试断言也应采用兼容模式:var value = reader.IsDBNull(i) ? null : reader.GetString(i); 后用 string.IsNullOrEmpty(value) 断言。数据迁移决策则是:把既有 NULL 转成空串、用 NULLIF(column, '') 把空串转成 NULL、或保持现状仅改应用逻辑,三选一并记录在案。
2. ROWNUM 分页 → LIMIT/OFFSET
Oracle 的 ROWNUM 在 ORDER BY 之前赋值,导致 ROWNUM 过滤对无序结果集不确定;而 PostgreSQL 的 LIMIT 在 ORDER BY 之后生效(见 oracle-rownum-pagination.md)。
-- Oracle:取按日期排序的前 10 条需要子查询包裹
SELECT * FROM (
SELECT * FROM orders ORDER BY created_at DESC
) WHERE ROWNUM <= 10;
-- PostgreSQL 等价的直白写法
SELECT * FROM orders ORDER BY created_at DESC LIMIT 10;
-- Oracle:第 11–20 条需要双重包裹子查询
SELECT * FROM (
SELECT t.*, ROWNUM rn FROM (
SELECT * FROM orders ORDER BY created_at DESC
) t WHERE ROWNUM <= 20
) WHERE rn > 10;
-- PostgreSQL:LIMIT/OFFSET 直接解决
SELECT * FROM orders ORDER BY created_at DESC LIMIT 10 OFFSET 10;
注意在 PL/pgSQL 中参数风格要改用 $n。搜索范围不止存储过程,还包括 C# 字符串字面量、StringBuilder 与查询构建器中的 ROWNUM。测试务必断言"返回的是正确的 n 行且顺序正确",而不只是数量正确。
3. NVL / NVL2 / DECODE → COALESCE / CASE
Oracle 的 NVL、NVL2、DECODE 在标准 SQL 中没有直接等价物(见 oracle-nvl-decode-functions.md):
-- NVL 双参数场景与 COALESCE 语义等价
NVL(column_name, 'default') → COALESCE(column_name, 'default')
-- NVL2 需改 CASE
NVL2(column_name, 'has value', 'no value')
→ CASE WHEN column_name IS NOT NULL THEN 'has value' ELSE 'no value' END
-- DECODE 是等值分支
DECODE(status, 1, 'Active', 2, 'Inactive', 'Unknown')
→ CASE status WHEN 1 THEN 'Active' WHEN 2 THEN 'Inactive' ELSE 'Unknown' END
最易出现静默差异的是 DECODE 把两个 NULL 视为相等,而 CASE col WHEN NULL 不会命中——搜索值含 NULL 时必须改用 CASE WHEN col IS NULL ...。此外 COALESCE 在 PostgreSQL 中类型敏感,两个实参类型不一致时需要显式 CAST。测试应专门覆盖 NULL 输入。
4. SYSDATE / 序列 NEXTVAL / DUAL
Oracle 的日期函数、序列调用语法与 DUAL 假表均需逐一替换(见 oracle-sysdate-sequences-dual.md):
SYSDATE→NOW()/CURRENT_TIMESTAMP(带时区)、CURRENT_DATE(仅日期)、LOCALTIMESTAMP(不带时区,最接近 SYSDATE 语义);- 类型警告:Oracle
DATE同时存日期和时间,PostgreSQLDATE只存日期。若 Oracle 的DATE列携带时间分量,目标列应为TIMESTAMP而非DATE; sequence_name.NEXTVAL→nextval('sequence_name')(函数调用、序列名作为带引号字符串参数);CURRVAL→currval('sequence_name');若 Phase 4 已在列上设置了DEFAULT nextval(...),应用代码可省略序列调用并从 INSERT 中移除该列;SELECT expr FROM DUAL→ 直接SELECT expr(PostgreSQL 无 DUAL,表达式无需 FROM)。若安装了orafce,其提供的DUAL视图可让旧查询不改即用,但应只作为过渡手段。
5. REF CURSOR:驱动层行为天差地别
这是客户端代码迁移中最典型的"反直觉"差异(见 postgres-refcursor-handling.md):Oracle 驱动(ODP.NET)会自动解开 SYS_REFCURSOR 输出参数,数据读取器直接暴露结果集;而 Npgsql 返回的是一个游标名字符串(如 "<unnamed portal 1>"),客户端必须再发一条 FETCH ALL FROM "<cursor_name>" 才能取到实际数据。
若不处理,会出现典型的 System.IndexOutOfRangeException: Field not found in row: <column_name>——因为读取器里只有游标名参数。另一个关键约束:PostgreSQL 的 refcursor 是事务作用域的,过程调用与 FETCH 必须在同一个显式事务内执行,否则 autocommit 下游标可能在抓取前就被关闭。仓库给出了可复用的 C# 模式:
public IEnumerable<User> GetUsers(int departmentId)
{
var users = new List<User>();
using var connection = new NpgsqlConnection(connectionString);
connection.Open();
// Refcursors 是事务作用域的——把 CALL 与 FETCH 包在同一个事务里。
using var tx = connection.BeginTransaction();
using var command = new NpgsqlCommand("get_users", connection, tx)
{
CommandType = CommandType.StoredProcedure
};
command.Parameters.AddWithValue("p_department_id", departmentId);
var refcursorParam = new NpgsqlParameter("cur_result", NpgsqlDbType.Refcursor)
{
Direction = ParameterDirection.Output
};
command.Parameters.Add(refcursorParam);
command.ExecuteNonQuery(); // 执行过程、打开游标
string cursorName = (string)refcursorParam.Value; // 取回游标名
using var fetchCommand = new NpgsqlCommand($"FETCH ALL FROM \"{cursorName}\"", connection, tx);
using var reader = fetchCommand.ExecuteReader();
while (reader.Read())
{
users.Add(new User
{
UserId = reader.GetInt32(reader.GetOrdinal("user_id")),
UserName = reader.GetString(reader.GetOrdinal("user_name")),
Email = reader.GetString(reader.GetOrdinal("email"))
});
}
tx.Commit();
return users;
}
最佳实践是把"执行 → 取游标名 → FETCH 物化"封装成可复用 helper,在 helper 内部完成结果物化,避免把存活中的 NpgsqlDataReader 泄漏给调用方造成命令未被释放的歧义所有权问题。Oracle(ODP.NET)与 PostgreSQL(Npgsql)的关键差异可总结为:前者驱动托管游标生命周期与自动解包,后者需要显式的 FETCH ALL FROM、同一事务共享、多游标需多次 FETCH、游标保持打开直到抓取完成或事务结束。
6. 物化视图:快照不会自动刷新
PostgreSQL 的物化视图是静态快照,基表数据变化不会自动刷新依赖它的物化视图(见 postgres-materialized-view-refresh.md)。Oracle 时代"派生数据立即更新"的假设会失效,读路径可能返回过期行,集成测试也会因刷新时序不确定而出现"一次通过、一次间歇失败"的假象。
针对每条写入"喂给物化视图的基表"的迁移路径,都要有明确的刷新策略:
REFRESH MATERIALIZED VIEW my_view; -- 需要新鲜度时的即时刷新
REFRESH MATERIALIZED VIEW CONCURRENTLY my_view; -- 并发刷新,降低读阻塞(需有索引支持)
或接受陈旧窗口的定时/批量刷新。测试期望:修改基表的测试必须只在预期的刷新动作之后断言物化视图内容,并在适用时断言刷新前的陈旧行为,且每个特性应文档化其新鲜度是即时(immediate)还是最终(eventual)。
其他差异一览
参考索引 REFERENCE.md 还覆盖了更多点:Oracle 的 SELECT INTO 未找到数据抛 "no data found" 而 PostgreSQL 不抛,需显式处理 NOT FOUND;FROM(TABLE_NAME) 的多余括号要去掉;TO_CHAR(numeric) 无格式串在 PostgreSQL 不允许,改用 CAST(numeric AS TEXT);PostgreSQL 类型检查严格而 Oracle 隐式强转,需对字面量加引号或显式 cast;UNION ALL 分支谓词下推受限可能产生劣化执行计划,需审查计划并拆分或重塑查询;PostgreSQL 同一连接同时只能有一个活动命令,需物化结果或改用独立连接;时区方面 CURRENT_TIMESTAMP/NOW() 返回 UTC 归一化的 timestamptz,Npgsql 暴露的 DateTime.Kind=Unspecified,需要在连接打开与应用代码处强制 UTC。
七、Agent 与技能生态的协作图谱
该 Agent 的设计精髓在于"方法在 Agent、知识在技能、差异在参考库"。它按阶段调用 8 项专用技能,仓库中均有对应目录:
| 阶段 | 调用的技能 | 职责 |
|---|---|---|
| Phase 2 | reviewing-oracle-to-postgres-migration | 对照行为差异知识库做风险评估与迁移验证 |
| Phase 3 | planning-oracle-to-postgres-migration-integration-testing | 规划 Oracle 集成测试 |
| Phase 3 | scaffolding-oracle-to-postgres-migration-test-project | 搭建面向 Oracle 的 xUnit 测试项目骨架 |
| Phase 3 | creating-oracle-to-postgres-migration-integration-tests | 依据测试计划编写集成测试 |
| Phase 5 | migrating-oracle-to-postgres-data-access-code | 迁移数据访问层代码(checklist 驱动) |
| Phase 4/6 | migrating-oracle-to-postgres-stored-procedures | PL/SQL → PL/pgSQL 存储过程迁移 |
| Phase 1 | creating-oracle-to-postgres-master-migration-plan | 生成解决方案级主迁移计划 |
| 各阶段 | creating-oracle-to-postgres-migration-bug-report | 将行为偏差记录为结构化 bug report |
此外,Phase 6 文档提到的"修复循环(fix loop instructions)"、"结构化 bug report(⏳ IN PROGRESS 状态)"等约定,也与上述技能目录的内容一一对应,形成"Agent 编排 + 技能提供领域知识 + 产物落盘可追溯"的完整体系。
八、给迁移实践者的行动清单
结合该 Agent 的方法论,无论你是否直接使用 Copilot 运行它,以下实践都值得在 Oracle→PostgreSQL 迁移中借鉴:
- 先立基线再谈迁移:在动手改任何代码前,先用 xUnit 集成测试锁住 Oracle 的既有行为;基线通过才算起点干净;
- 复制而非改写:代码与测试迁移都采用
.Postgres后缀副本,原 Oracle 项目与测试始终保持纯净可运行,让两条路径可随时对比验证; - schema 冻结在代码迁移期:代码与测试迁移期间不碰 schema,把 DDL 变化集中在单独阶段,避免"改代码与改 schema 互相污染"导致无法定位回归;
- 差异建库:把空串/NULL、
ROWNUM、NVL/DECODE、refcursor、时区、物化视图刷新等行为差异整理成团队共享的对照参考,而不是依赖个人经验; - 产物文档化:主迁移计划、逐项目风险分析、编号迁移清单、bug report 全部落盘到固定目录,迁移完成即形成一份可交接的工程档案。
整套方法论的核心逻辑是:用分阶段门禁控制迁移风险,用测试基线替代口头约定,用行为差异知识库覆盖 Oracle/PostgreSQL 语义盲区,用用户亲手应用 DDL守住数据库变更的责任边界——这正是大规模数据库迁移工程中把不确定降到最低的可执行范式。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00