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.pswp.cn/diannao/85137.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PCIe-PCI、PCIe中断机制概述

PCI、PCIe中断概述 PCIe 中断机制在继承 PCI 传统中断&#xff08;INTx&#xff09;的基础上&#xff0c;引入了更高效的 MSI/MSI-X 方案&#xff0c;以提升设备性能并减少 CPU 轮询开销。以下是核心要点及技术演进&#xff1a; ⚙️ ​​一、PCIe 中断类型与演进​​ ​​IN…

改进自己的图片 app

1. 起因&#xff0c; 目的: 前面我写过一个图片 app &#xff0c; 最新做了些改动。 把原来的一列&#xff0c;改为3列&#xff0c; 继续使用瀑布流手机上使用&#xff0c;更流畅&#xff0c;横屏显示为2列。 2. 先看效果 3. 过程: 过程太细碎了&#xff0c;这里只是做一下…

【HTML-15】HTML表单:构建交互式网页的基石

表单是HTML中最强大的功能之一&#xff0c;它允许网页收集用户输入并与服务器进行交互。无论是简单的搜索框、登录页面&#xff0c;还是复杂的多步骤调查问卷&#xff0c;表单都是实现这些功能的核心元素。本文将深入探讨HTML表单的各个方面&#xff0c;帮助您构建高效、用户友…

关于智能体接入后端,在Apifox能够传参数给智能体的测试

from flask import Flask, request, jsonify, render_template import requests import json # 用于解析嵌套的 JSON 字符串app Flask(__name__)COZE_BOT_ID 7508736911423963162 COZE_API_KEY pat_cHXqrFzcvtktfmmlp4pjF3O2qmjioQW46uU8UNbUugyvSlFZclklpunc53DbR8ws COZE…

SQL进阶之旅 Day 8:窗口函数实用技巧

【SQL进阶之旅 Day 8】窗口函数实用技巧 在现代数据库开发中&#xff0c;处理复杂的业务逻辑和大规模数据时&#xff0c;仅仅依靠传统的GROUP BY和JOIN操作已经无法满足需求。**窗口函数&#xff08;Window Function&#xff09;**作为SQL标准的一部分&#xff0c;为开发者提供…

编译rustdesk,使用flutter、hwcodec硬件编解码

目录 安装相应的环境安装visual studio安装vpkg安装rust开发环境安装llvm和clang编译源码下载源码使用Sciter作为UI的(已弃用)使用flutter作为UI的(主流)下载flutter sdk桥接静默安装最近某desk免费的限制越来越多,实在没办法,平时远程控制用的比较多,只能用rustdesk了,…

由反汇编代码确定结构体的完整声明

C程序中遇到下面的代码 typedef struct {int left;a_struct a[CNT];int right; } b_struct;void test( int i, b_struct *bp) {int nbp->leftbp->right;a_struct *ap&bp->a[i];ap->x[ap->idx]n; } 下面是test函数的反汇编代码 结合C程序中的代码与test函数…

鸿蒙OSUniApp复杂表单与动态验证实践:打造高效的移动端表单解决方案#三方框架 #Uniapp

UniApp复杂表单与动态验证实践&#xff1a;打造高效的移动端表单解决方案 引言 在移动应用开发中&#xff0c;表单处理一直是一个既常见又具有挑战性的任务。随着HarmonyOS生态的蓬勃发展&#xff0c;越来越多的开发者开始关注跨平台解决方案。本文将深入探讨如何使用UniApp框…

Python学习(2) ----- Python的数据类型及其集合操作

在 Python 中&#xff0c;一切皆对象&#xff0c;每个对象都有类型。下面是 Python 中的常见内置类型分类和示例&#xff1a; &#x1f7e1; 1. 数字类型&#xff08;Numeric Types&#xff09; 类型说明示例int整数5, -42float浮点数3.14, -0.5complex复数1 2j a 10 …

深入解析Go语言数据类型:从底层到高级应用

引言 Go语言的数据类型系统设计体现了​​简洁性​​与​​高效性​​的完美平衡。作为静态编译型语言&#xff0c;Go提供了丰富的数据类型支持&#xff0c;从基础数值类型到高级并发原语&#xff0c;都经过精心设计。本文将深入剖析Go语言数据类型体系&#xff0c;揭示其底层…

数据交易场景的数据质量评估

在现代数字化时代&#xff0c;数据已成为推动商业发展的核心驱动力。基于不同的交易产品和业务场景&#xff0c;数据产品的质量和准确性直接影响到数据资产的价值及其在市场中的流通性。因此&#xff0c;为数据产品提供全面、深入的数据质量评估报告&#xff0c;不仅有助于提升…

Java 对接 Office 365 邮箱全攻略:OAuth2 认证 + JDK8 兼容 + Spring Boot 集成(2025 版)

&#x1f6a8; 重要通知&#xff1a;微软强制 OAuth2&#xff0c;传统认证已失效&#xff01; 2023 年 10 月起&#xff0c;Office 365 全面禁用用户名 密码认证&#xff0c;Java 开发者必须通过OAuth 2.0实现邮件发送。本文针对 CSDN 技术栈&#xff0c;提供从 Azure AD 配置…

一文详谈Linux中的时间管理和定时器编程

&#xff08;目录&#xff09; 先说一些在计算机中需要用到时间的地方&#xff1a;系统日志log、OS调度(时间片、定时器)等等~~ 时间的计量 计时的方式发展&#xff1a;日晷、沙漏 -> 机械钟 -> 石英振荡器、晶振 -> 铯原子钟 -> 氢原子钟 计算机中的计时方式&…

使用FastAPI+Sqlalchemy从一个数据库向另一个数据库更新数据(sql语句版)

from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker # 配置数据库连接&#xff08;示例为PostgreSQL->MySQL&#xff09; SRC_DB_URL postgresql://user:passsource_host:5432/source_db DST_DB_URL mysqlpymysql://user:passdest_hos…

基于python脚本进行Maxwell自动化仿真

本文为博主进行Maxwell自动化研究过程的学习记录&#xff0c;同时对Maxwell自动化脚本&#xff08;pythonIron&#xff09;实现方法进行分享。 文章目录 脚本使用方法脚本录制与查看常用脚本代码通用开头定义项目调整设计变量软件内对应位置脚本 设置求解器软件内对应位置脚本…

pikachu通关教程-RCE

目录 RCE(remote command/code execute)概述: exec "ping" 管道符 乱码问题 RCE(remote command/code execute)概述: RCE漏洞&#xff0c;可以让攻击者直接向后台服务器远程注入操作系统命令或者代码&#xff0c;从而控制后台系统 分为远程代码和远程命令两种.当…

JavaScript性能优化全景指南

JavaScript性能优化全景指南 Ⅰ. 加载性能优化 1.1 代码分割与懒加载 动态导入(ES2020) javascript // 路由级代码分割 const ProductPage () > import(/* webpackChunkName: "product" */ ./ProductPage.vue); // 交互驱动加载 document.querySelector(#char…

BaseTypeHandler用法-笔记

1.BaseTypeHandler简介 org.apache.ibatis.type.BaseTypeHandler 是 MyBatis 提供的一个抽象类&#xff0c;通过继承该类并实现关键方法&#xff0c;可用于实现 Java 类型 与 JDBC 类型 之间的双向转换。当数据库字段类型与 Java 对象属性类型不一致时&#xff08;如&#xff…

t015-预报名管理系统设计与实现 【含源码!!!】

项目演示地址 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装预报名管理系统软件来发挥其高效地信息处理的…

Day12 - 计算机网络 - HTTP

HTTP常用状态码及含义&#xff1f; 301和302区别&#xff1f; 301&#xff1a;永久性移动&#xff0c;请求的资源已被永久移动到新位置。服务器返回此响应时&#xff0c;会返回新的资源地址。302&#xff1a;临时性性移动&#xff0c;服务器从另外的地址响应资源&#xff0c;但…