Mysql迁移到Oracle踩坑

Posted N个程序猿的日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql迁移到Oracle踩坑相关的知识,希望对你有一定的参考价值。

公司要求兼容Oracle,将踩过的坑共享出来供大家参考。


1. limit转换

mysql:
selelct a,b,c from tableA where a=1 order by b limit 1,10;
oracle:
select * from (
select A.*, rowum r from (
select a,b,c from tableA where a=1 order by b
) A
where rownum <![CDATA[ <= ]]> 10
) B
where r > 1;


2. insert坑

mysql:
insert into tableA (id,name,type) value (1,2,3);
insert into tableA (id,name,type) values(1,2,3);
oracle:
insert into tableA (id,name,type) values (1,2,3);


3. group by

mysql:
select a,b,c from tableA where a = 1 group by b;
select count(1),b from tableA group by a;
oracle:

有group by时,select子句中要么只有聚合函数或为 “*”,要么必须包含group的子句(且要比其他子句出现的早);

select b,a,c from tableA where a =1 group by b;
select count(1),a,b from tableA group by a;

4. 日期

mysql:
select * from tableA where a > "2020-01-01 13:10:00";
select * from tableA where b = "2020-01-01 13:10:00";
oracle:
-- 12小时制的pattern写作'yyyy-MM-dd hh12:mi:ss',24小时制写作'yyyy-MM-dd hh24:mi:ss'
select * from tableA where a > to_date('2020-01-01 13:10:00','yyyy-MM-dd hh24:mi:ss');
-- 当b是varchar2类型时:
select * from tableA where b = '2020-01-01 13:10:00';
-- 当传来的参数是date类型,表中数据为varchar2类型时
select * from tableA where b = to_char('2020-01-01 13:10:00','yyyy-MM-dd hh24:mi:ss');


5. concat()函数

mysql:
select * from tableA where a like concat('%',#{a},'%');
oracle:
-- 注意:Oracle是单引号,Oracle的单双引号意义不同
select * from tableA where a like concat(concat('%',#{a}),'%');


6. 单引号双引号

mysql:
select * from tableA where a like concat("%",#{a},"%");
select * from tableA where a like concat('%',#{a},'%');
oracle:
-- 注意这里是单引号
select * from tableA where a like concat(concat('%',#{a}),'%');


7. 字段名为date

mysql:
select * from tableA where date = #{date};
oracle:
-- 这里是双引号
select * from tableA where "date" = #{date};


8. left()函数

mysql:
select left(a,4) from tableA;
oracle:
select substr(a,0,4) from tableA;


9. 解决id自增问题

-- 在表中创建sequence和对应的触发器,在向指定表插入数据时会自动填入id;

-- 避免重复,若没有创建过,可以不添加这句话
drop sequence tableA_id;

-- 创建sequence
create sequence tableA_id
       -- id的最小值
      minvalue 1  
       -- id的最大值,若没有或者不确定可以用 nomaxvalue
      maxvalue 9999999
       -- 递增量
      increment by 1    
       -- id的起始值
      start with 1
       -- 是否循环
      nocycle
       -- 是否设置缓存
      nocache;

-- 创建触发器
create or replace trigger tableA_id_trigger
-- 将触发器与tableA的insert事件绑定
before insert on tableA for each row
begin
-- tableA_id.nextval即为自动生成的id
select tableA_id.nextval into:new.id from dual;
end;
在 mapper.xml 中有填写id字段需求时也可以在有sequence的前提下写作:
<!-- tableA_id是数据库中已经创建的sequence -->
<insert id="insertTest" parameterType="java.util.Map" keyProperty="id">
      insert into tableA (id, col1, col2)
      values ( tableA_id.nextval, #{col1}, #{col2})
</insert>

10.仅针对插入、更新脚本:mysql的&和oracle的||符号

insert或者update语句中有字段包含”&“符号时,需要用||连接符或者:

mysql:
字符:"abc&def"

oracle:

字符:'abc'||'&'||'def'

11. 仅针对插入、更新脚本:mysql的转义字符 \ 和oracle的 '

mysql:
字符:{text:\'this is a test\',value:\'nothing\'}
oracle:
字符:{text:''this is a test'',value:''nothing''}

12. 字段大小写

oracle:
-- Oracle默认自动转大写,结果为tableA中的id、Id、iD、ID字段对应值;
select id  from tableA;
-- 可以理解成:单引号标识为字符id,结果为tableA中的id字段对应值;
select 'id' from tableA;
-- 同date等特殊字段,结果为tableA中的id、Id、iD、ID字段对应值;
select "id" from tableA;
-- 结果为tableA中的id、Id、iD、ID字段对应值;
select ID  from tableA;
-- 结果为tableA中的ID字段对应值;
select 'ID' from tableA;
-- 结果为tableA中的id、Id、iD、ID字段对应值;
select "ID" from tableA;



以上是关于Mysql迁移到Oracle踩坑的主要内容,如果未能解决你的问题,请参考以下文章

oracle迁移到mysql注意事项

oracle数据迁移到mysql中去,数据类型不一致

怎么将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL

从 mysql 迁移到 oracle 命中 ora-01400

程序员踩坑之旅:将 75000 行 iOS 原生代码迁移到 Flutter!

如何将ORACLE的数据迁移到MYSQL