Oracle转PostgreSQL
Oracle转PostgreSQL
PostgreSQL 13.1 手册
阿里云帮助中心
前言
从2019年开始,就有一个很火热的话题:“去O化”。O就是oracle,也就是将oracle替换成别的数据库。
原因:
- oracle是收费的,为了进一步降低成本;
- 以美国为首的西方国家对华科技种种遏制行为,最近越闹越厉害,最近docker的付费服务就禁止中国企业使用;
- 甲骨文公司中国区大幅度裁员,或将放弃中国市场也说不定;
- 2020年12月31起,甲骨文公司将不再对oracle11.2版本提供技术支持,即出现bug也不会维护了。
迁移点
1、jar包/maven依赖的更换:
驱动包要换成postgresql-xxx.jrex.jar
,x
表示版本。如果是maven项目,则添加如下依赖:
<dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>版本</version>
</dependency>
2、driverClassName等信息的更换:
datasource.driverClassName=org.postgresql.Driver
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
3、字段类型问题:
- 主外键字段类型问题:A表的主键在B表做外键时,这个字段在两张表的类型一定要一致,否则连接查询会报错。
- 实体类与数据表字段类型问题:实体类字段类型一定要与数据表字段类型对应,否则映射的时候就报错了。
- 查询条件的字段类型问题:假如数据表中id字段类型是int4,查询条件传String类型的1,是会报错的,要用Integer类型,而oracle不会报错,会自动进行类型转换。
4、postgre与java字段类型对照表:
以下是常用字段类型对照:
postgre | java |
---|---|
varchar | String |
char | String |
text | String |
int2/int4 | Integer |
int8 | Long |
float4 | Float |
float8/money | Double |
numeric | Bigdecimal |
bool | Boolean |
bytea | byte[] |
5、序列问题:
- oracle获取序列:
my_sequece.nextval
- postgre获取序列:
nextval('my_sequece')
6、sysdate替换方案:
oracle | postgre | |
---|---|---|
当前日期 时间 | sysdate | now() current_timestamp |
当前日期 | trunc(sysdate) | now() :: date |
?分钟前 | sysdate - ?/24/60 | now() - (? || ‘min’)::interval |
?天前 | sysdate - ? | now() - (? || ‘day’)::interval |
7、NVL函数替换方案:
oracle中的NVL(arg1, arg2)
用来设置默认值,arg1为空就设置为arg2。postgre中可以用coalesce(arg1, arg2)
实现相同效果。
8、rownum实现方法:
rownum使用场景1:分页输出
比如要查询user表第一页,每页显示10条数据:
- oracle中用rownum进行分页:
select * from (select aa.*, rownum rn from (select * from user) aa where rownum <= 11 ) where rn > 1;
- postgre中用limit进行分页:
select * from user limit 10 offset 1
查询user表5条数据:
- oracle写法:
select * from user where rownum <= 5
- postgre写法:
select * from user limit 5
rownum使用场景2:生成序列值
- oracle写法:使用rownum递增的特性来生成序列值。
SQL> ALTER TABLE t1 ADD seqno NUMBER(3);
SQL> UPDATE t1 SET seqno = ROWNUM;
- postgre写法:使用临时序列来为某个字段生成序列值。
bill=# create temp sequence if not exists tmp_seq;
CREATE SEQUENCE
bill=# alter sequence tmp_seq restart with 1;
ALTER SEQUENCE
bill=# alter table t1 add column col1 int;
ALTER TABLE
bill=# update t1 set col1=nextval('tmp_seq');
UPDATE 10
rownum使用场景3:实现行号
- postgre写法:
select row_number()over() as rownum, * from t1
9、不等于的问题:
postgre中column !=-?
会报错,负号和数字要用括号括起来,或者!=
统一改成<>
。
10、数字类型字段模糊查询问题:
非String类型的字段要进行模糊查询,需要先将数据库字段类型转成varchar,如下:
and cast(user_phone as varchar) LIKE ?
11、update语句相关问题:
postgre中,update语句不能设置表别名,否则会报错。
12、count和order by的问题:
select count(*)
的语句不能加order by
,否则会报错。
13、order by的问题:
group by
的字段一定要在select
中查出来,并且如果group by
的字段有使用函数,select
的时候也要使用相同的函数,例如:
select upper(user_id) from user order by upper(user_id)
14、blob类型的问题:
oracle中用blob类型可以存储文件,在java中也用blob类型对应。postgre与之对应的是bytea,在java中用byte[]数组对应就可以了。
15、clob类型的问题:
oracle中用clob存储大文本,在java中也用clob类型对应。postgre与之对应的是text,在java中直接用String对应就可以了。
16、decode函数问题:
oracle中的decode(arg1, arg2, arg3, arg4)
函数,表示:当 arg1 等于 arg2 时,取 arg3 ,否则取 arg4
。postgre中没有类似的函数,可以用如下方式实现:
case when arg1 = arg2 then arg3 else arg4 end
17、to_date函数的问题:
特别注意,postgre中to_date
函数转出来的是不带时分秒的时间,如果想要带时分秒的,需要用to_timestamp
。
18、substr函数的问题:
substr(arg, begin, num)
函数,表示对arg
进行截取,从第begin
位开始,截取num
个。oracle中,arg
可以是字符串也可以数字类型,但是postgre中只支持对字符串的截取,如果要对数字进行截取,得写成:SUBSTR(1.23 :: TEXT,1,3)
。还有一点,oracle中substr(1.23, -2)
表示截取最后两位,结果就是23,postgre中不支持这种用法,要实现相同功能,可以用right
函数:right(1.23::text, 2)
。
19、 listagg(column1, ‘,’) within group(column2)函数的问题:
这个函数的意思是将column2相同的多行记录的column1的值合并成一行,例如:
SELECT tr.tr_gw_no,listagg(tr.tr_status, ',') WITHIN GROUP(ORDER BY tr.tr_status) status
FROM trade tr
where tr_gw_no = 12198006or tr_gw_no = 12167001
GROUP BY tr.tr_gw_no;
postgre中可以用string_agg
函数实现相同的功能,具体用法如下:
SELECTtr_gw_no,string_agg ( tr_status :: TEXT, ',' ) status
FROMtrade
WHEREtr_gw_no = 12198006 OR tr_gw_no = 12167001
GROUP BYtr_gw_no;
20、start with connect by函数的问题:
oracle的这个函数是用来查树形结构的,即同一张的表的记录有父子级关系的那种。oracle中用法如下:
select module_idfrom sys_modules
start with module_id = ?
connect by prior module_id = module_fid;
这就表示查询module_id
为?
的所有子module,即父模块idmodule_fid
为?
的所有的记录。postgre可以用WITH RECURSIVE
实现相同的效果,如下:
WITH RECURSIVE subtabela AS (SELECTmodule_id FROMsys_modules WHEREmodule_id = ? UNION ALLSELECTtt.module_id FROMsys_modules ttINNER JOIN subtabela st ON tt.module_fid = st.module_id ) SELECT*
FROMsubtabela;
21、存储过程调用的问题:
postgre11开始,支持存储过程procedure,之前的版本只支持function。通过代码去调用存储过程时,要注意以下三点:
- 调用存储过程的sql语句不需要加大括号,加了大括号的调用的是function而不是procedure;
- 如果存储过程中用了事务,那个在代码中调用时就不要使用spring的事务了,否则会冲突;
- 如果存储过程有
inout
参数,表示这个即是输入又是输出参数,都要进行设置,oracle可以只当作输入或者输出来用。
比如现在有一个名为test_procedure(IN "id" int4, INOUT "result" int4)
的存储过程,java中调用方式如下:
Session session = sessionFactory.getCurrentSession();
Connection conn = session.connection();
CallableStatement cs = null;
Integer returnInfo = -1;
cs = conn.prepareCall("test_procedure(?,?)");
// oracle中调用要加大括号
// cs = conn.prepareCall("{test_procedure(?,?)}");
// 输入的参数
cs.setInt(1, id.intValue());
// 输出的参数
cs.setInt(2, -1); // oracle中这一行可以不用
cs.registerOutParameter(2, Types.INTEGER);
// 执行存储过程
cs.execute();
// 获取返回值,-1为操作异常
returnInfo = cs.getInt(2);
22、连接查询的问题:
oracle中外连接可以这样写:
select * from tableA a, tableB b where a.id = b.id(+);
有(+)
的一方是副表,另一方是主表,即上面那种写法表示左外连接。postgre不支持这种写法,可以用left join
代替。
23、instr函数的问题:
instr
函数表示包含,postgre中可以用strpos
函数替代。
Oracle转PostgreSQL相关推荐
- oracle 控制文件在哪里设置_从Oracle到PostgreSQL:最全控制文件
原文: 从Oracle到PostgreSQL:最全控制文件(上) https://www.enmotech.com/web/detail/1/770/1.html 从Oracle到PostgreSQL ...
- vs oracle带参数更新,Oracle vs PostgreSQL Develop(23) - PL(pg)sql(参数声明)
Oracle和PostgreSQL都提供了内置的编程语言(PL/SQL vs PL/pgSQL),在输入输出参数的声明上有较大的不同,如输入参数中存在inout/out参数,Oracle的函数可以有返 ...
- oracle迁移postsql的,osdba's blog : Oracle迁移PostgreSQL系列文章之二:merge语句
Oracle迁移PostgreSQL系列文章之二:merge语句 Posted on 2015-03-06 11:12:46 by osdba 我们知道,Oracle中有一个特别的merge语句.而P ...
- oracle在线sql数据库设计,一款在线ER模型设计工具,支持MySQL、SQLServer、Oracle、Postgresql...
在线QQ客服:1922638 专业的SQL Server.MySQL数据库同步软件 介绍一个在线ER模型生成工具,该工具可以在线为多个数据库的DDL文件生成ER模型图,并支持MySQL,SQLServ ...
- pg和oracle比较,Oracle与PostgreSQL使用差异对比与总结
JDBC连接: Oracle的jdbc连接字符串:db.url=jdbc:oracle:thin:@192.168.1.1:1521:ORCL Postgresql的连接字符串:db.url=jdbc ...
- 使用OmniDB数据库管理工具,管理Oracle/MariaDB/PostgreSQL等关系型数据库
参考来源:https://hub.docker.com/r/taivokasper/omnidb/ 使用OmniDB数据库管理工具 --管理Oracle/MariaDB/PostgreSQL等关系型数 ...
- ORACLE与PostgreSql的区别
http://blog.itpub.net/post/2316/10994 ORACLE与PostgreSql的区别 本文档主要从数据库开发角度来对比二者的区别,有一些二者相同之处,这里不再专门提出. ...
- Oracle/MySQL/PostgreSQL考题等你挑战(附假期活动获奖名单)
国庆期间,数据技术嘉年华为读者准备了做题赢门票的活动,10道极富挑战的Oracle/MySQL/PostgreSQL考题,选择任何一种答对7题即可免费获赠大会门票一张,这里公布一下获奖名单. 活动回顾 ...
- 从Oracle到PostgreSQL:一文掌握Checkpoint重要概念
墨墨导读:Checkpoint是数据库中重要的概念,无论在Oracle,MySQL这个概念,它主要功能是在检查点时刻,脏数据全部刷新到磁盘,以实现数据的一致性和完整性.PostgreSQL为什么要设计 ...
- 从Oracle到PostgreSQL:最全控制文件
墨墨导读:本文介绍了Oracle和PostgreSQL控制文件基本内容,对如何重建PostgreSQL控制文件进行了详细描述并进行了恢复测试. 控制文件内容 Oracle控制文件内容 从官方文档上可以 ...
最新文章
- 报名 | “AI Time”系列论道知识图谱:知识赋能智能与智能产生知识
- 室外电磁赛道铺设补充说明
- [poj] 2318 TOYS || 判断点在多边形内
- jquery 获取Input 值
- [密码学基础][信息安全][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第11篇]DLP、CDH和DDH问题是什么?
- java 如何重写迭代器,如何用Java按需定制自己的迭代器
- c语言uint32_使C语言实现面向对象的三个要素,你掌握了吗?
- 信息学奥赛一本通(1006:A+B问题)
- 《scikit-learn》数据标准化与SVM之SVC
- linux oracle查询乱码问题,linux中oracle中文乱码解决方法
- ftp改为sftp_ftp自动传输软件,ftp自动传输软件使用方法详细介绍
- Django 09-2 模型层 字段
- 最好用的10款手机库存管理软件,我来教你怎么选
- html网页设计插件,适用于网页设计的Photoshop插件包
- 面试官的窒息逼问: 到底什么是面向接口编程?
- 全国各省女孩性格+美丽程度比较分析!
- 数学符号Span的含义
- 【面试题】15.项目相关
- Maven下载sources时报错java.lang.RuntimeException: Cannot reconnect
- QT .pro文件详解