当前位置: 首页 > news >正文

Oracle向PG转移建议以及注意点

Oracle向PG转移建议以及注意点

✅ 一、语法差异与迁移建议

1. 包结构(Package)

  • Oracle 支持 PACKAGEPACKAGE BODY 分离定义。
  • PostgreSQL 不支持包结构,需将每个函数/过程单独定义。

迁移建议:

  • PACKAGE 包中的每个函数和存储过程拆分为独立的 FUNCTIONPROCEDURE
  • 使用模式(Schema)来组织这些对象,模拟 Oracle 的包结构逻辑。

2. 变量声明和赋值

  • Oracle 中变量在 DECLARE 部分声明。
  • PostgreSQL 使用 %ROWTYPE 类似,但变量声明需放在 DECLARE 块中。

注意点:

  • SELECT INTO 在 PostgreSQL 中用于赋值。
  • 确保使用 PERFORM 替代无返回值的查询(如日志插入)。
-- Oraclea A%Rowtype;-- PostgreSQL
DECLAREa A%ROWTYPE;

3. 异常处理

  • Oracle 使用 WHEN OTHERS THEN ...
  • PostgreSQL 使用 EXCEPTION WHEN OTHERS THEN ...

迁移建议:

  • 替换 RAISE_APPLICATION_ERROR(xxx, '错误信息')RAISE EXCEPTION '错误信息'
-- Oracle
Raise_Application_Error(xxx, 'DataNotFound' || Geterrmsg);
-- PostgreSQL
RAISE EXCEPTION 'DataNotFound: %', SQLERRM;

4. 表名大小写敏感

  • Oracle 默认大写表名。
  • PostgreSQL 默认小写,引用原大小写需加双引号。

建议:

  • 表名统一使用小写,避免问题。
  • 如有保留原名需求,用双引号包裹。

5. 序列和 GUID

  • Oracle 使用 SYS_GUID()
  • PostgreSQL 可使用 uuid_generate_v4()(需安装 uuid-ossp 扩展)

6. 日期计算

  • Oracle 中 Sysdate 获取当前时间。
  • PostgreSQL 使用 NOW()CURRENT_TIMESTAMP
-- Oracle
createdate := Sysdate;
-- PostgreSQL
createdate := NOW();

7. 时间差计算

  • Oracle 时间差 (Sysdate - Starttime) * 24 * 60 * 60 * 1000
  • PostgreSQL 使用 EXTRACT(EPOCH FROM ...) 转换为毫秒
-- Oracle
Durtime = (Sysdate - Starttime) * 24 * 60 * 60 * 1000
-- PostgreSQL
durtime := EXTRACT(EPOCH FROM (NOW() - starttime)) * 1000;

8. 数据库链接(如 @Mysqlct

  • Oracle 支持通过数据库链接访问远程表。
  • PostgreSQL 可以使用 dblinkpostgres_fdw 扩展实现。
-- 示例:使用 dblink 查询远程用户
SELECT * FROM dblink('host=... dbname=... user=...', 'SELECT * FROM sys_user') AS t(user_id TEXT, user_name TEXT);

✅ 二、迁移工具建议

工具功能
ora2pg自动化转换 Oracle 到 PostgreSQL(这种方式可以迁移表结构和数据,存储过程和函数可能还是需要手工迁移)
AWS Schema Conversion Tool提供图形界面辅助迁移
dataX提供表数据迁移(使用DataX迁移后需要注意数字类型精度!!)
手动调整对于复杂逻辑更可靠,尤其是异常处理、事务控制等

✅ 三、测试建议

  1. 单元测试

    • 每个函数/过程单独验证输入输出。
    • 使用 pgTAPPL/pgSQL 测试框架。
  2. 性能测试

    • 观察执行计划是否合理。
    • 检查索引是否缺失或冗余。
  3. 日志记录

    • 迁移过程中建议启用 [LOG] 输出调试信息。

✅ 四、存储过程声明结构对比

Oracle 函数

Function funcName(v_Text Varchar2) Return returnType%Rowtype AsfieldName fieldType%Rowtype;
Begin//具体逻辑/////Return fieldName;
Exception//异常处理When No_Data_Found ThenRaise_Application_Error(xxxx, 'Data Not Found' || Geterrmsg);When Too_Many_Rows ThenRaise_Application_Error(xxxx, 'Too Many Rows' || Geterrmsg);When Others ThenRaise_Application_Error(xxxx, 'Unknow Err' || Geterrmsg);
End;

PostgreSQL 函数

CREATE OR REPLACE FUNCTION funcName(v_text VARCHAR)
RETURNS returnType
LANGUAGE plpgsql
AS $$
DECLAREfiledName fieldType%ROWTYPE;
BEGIN//具体逻辑///////异常处理IF NOT FOUND THENRAISE EXCEPTION 'Data Not Found: %', SQLERRM;END IF;RETURN funcName;
EXCEPTIONWHEN TOO_MANY_ROWS THENRAISE EXCEPTION 'Too Many Rows: %', SQLERRM;WHEN OTHERS THENRAISE EXCEPTION 'Unknow Err: %', SQLERRM;
END;
$$;

✅ 五、总结

迁移要点OraclePostgreSQL
包结构支持不支持
异常处理WHEN OTHERS THENEXCEPTION WHEN OTHERS THEN
GUIDSYS_GUID()uuid_generate_v4()
时间函数SYSDATENOW()
表名大小写默认大写默认小写
序列生成SEQUENCE.NEXTVALnextval('seq')
数据库链接支持使用 dblink / fdw
函数定义FUNCTIONCREATE OR REPLACE FUNCTION
存储过程PROCEDURECREATE OR REPLACE FUNCTION

注:

  1. 使用Ora2pg迁移时,对于复杂的存储过程和函数无法正确转换,需要手工迁移,若有更好的解决方案,可以评论或私聊,我们一起研究一下。
  2. 对于某些特殊的数据类型如bool,使用ora2pg迁移后,可能会被转成数字类型,需要后置手动修改。
  3. psql schema postgres -c "SET session_replication_role = replica;" -f data.sql 使用 SET session_replication_role = replica可以忽略约束进行数据导入。

坑点记录

一、语法相关

1. 异常对应关系

PostgreSQL Error Codes(PGSQL 异常Code文档)

2. 触发器不支持针对某个字段监控

Oracle迁移PGSQL_触发器
...BEFORE UPDATE OF xxxxx ON xxxx...
需要结合功能,判断修改方案。

3. PGSQL没有Package概念,需要把OraclePackage包中的存储过程和函数等,单独拆出来,并按PGSQL方言修改。

二、ORM相关

1. Mybatis PGSQL CallableStatement 不支持命名参数绑定

解决方式:不使用命名参数绑定的方式,直接拼接

  • 转义全包
<![CDATA[ CALL XXXXXXXX('${p1}','${p2}')
]]>
  • 使用{},这个方法暂时还没有验证

2. Mybatis 日志开放

<setting name="logImpl" value="STDOUT_LOGGING" />

3. @Select注解结尾不要分号 ;

相关SQL记录

ORACLE查询某个模式下所有number类型的字段信息

SELECT a.table_name,a.column_name,a.data_type,a.data_precision,a.data_scale
FROM all_tab_columns a
WHERE a.owner = 'SD'AND a.TABLE_NAME LIKE 'SD%'AND a.data_type = 'NUMBER'
ORDER BY TABLE_NAME ASC,COLUMN_NAME asc;

PostgreSQL查询number类型字段信息

SELECT table_schema AS schema_name,table_name,column_name,data_type,numeric_precision AS precision,numeric_scale AS scale
FROM information_schema.columns
WHERE table_schema = 'public'AND data_type IN ('smallint', 'integer', 'bigint','decimal', 'numeric', 'real', 'double precision');
http://www.xdnf.cn/news/683371.html

相关文章:

  • 57页 @《人工智能生命体 新启点》中國龍 原创连载
  • IvorySQL 核心技术解读:双 Parser 架构如何定义数据库兼容性?
  • python训练营打卡第36天
  • 竞赛小算法总结(二):gcdlcm,拓展欧几里得线性同余,逆元(含代码详解)
  • AE的ai图层导到Ai
  • spring4第2课-ioc控制反转-依赖注入,是为了解决耦合问题
  • WIN10 安装dify ollama搭建工作流agent
  • 两种主流检索技术:BM25(基于关键词匹配)和向量相似度检索
  • LVGL(Flex布局)
  • Docker修改镜像存放位置
  • qiankun 子应用怎样通过 props拿到子应用【注册之后挂载之前】主应用中发生变更的数据
  • vue2轮播图组件
  • 计算机网络实验课(二)——抓取网络数据包,并实现根据条件过滤抓取的以太网帧,分析帧结构
  • 如何检查液质联用仪LCMS的真空度
  • 提升前端性能:减少DOM操作
  • 在线项目管理工具对比:Trello、Worktile等20款软件测评
  • Java的Spring Cloud生态中实现SSE(Server-Sent Events)服务端实践
  • YoloV11改进策略:卷积篇-风车卷积-即插即用
  • 代码随想录算法训练营第60期第四十九天打卡
  • day05-常用API(二):Lambda、方法引用详解
  • Python装饰器与异常捕获的高级用法详解
  • 基于 STM32 的农村污水处理控制系统设计与实现
  • @vue/composition-api
  • uniapp-商城-72-shop(5-商品列表,购物车实现回顾)
  • Linux 6.15 内核发布,新功能
  • 【免费】【无需登录/关注】坐标系批量转换与可视化网页工具
  • 31. 自动化测试开发之实现INI配置文件解析
  • 从CPU缓存出发对引用池进行优化
  • C51-指针函数
  • Linux编译器——gcc/g++的使用