背景:
原来使用的是mysql:5.7,现在需要适配oracle数据库;
项目框架:SpringBoot:2.2.11.RELEASE + MybatisPlus:3.3.2
问题总结:
1、名字长度
oracle12.1的表、字段、索引名、视图名命名长度不能超过30,12.2版本以后即可支持;
2、默认值丢失
在mysql中有默认值,迁移到oracle中没有设置默认值;
3、注意字段大小写问题
4、时间字符串格式
oracle需要使用to_date()函数转换:
TO_DATE( '2022-06-07 00:00:00', 'SYYYY-MM-DD HH24:MI:SS' )
5、order by
oracle的order by 字段不在group by中就会报错;
6、sql末尾不能加分号 ";"
7、引号、as、关键字问题:
sql语法的支持 | 反单引号 · | 单引号 ' | 双引号 " | as 别名 |
---|---|---|---|---|
oracle字段名 | × | 支持 | × | 支持 |
mysql字段名 | 支持 | × 识别为字符串了 | × 识别为字符串了 | 支持 |
oracle 字段 as 别名 | × | × | 支持 | - |
mysql字段 as 别名 | 支持 | 支持 | 支持 | - |
oracle表名 | × | × | 支持区分大小写 | × |
mysql表名 | 支持 | × | × | 支持 |
oracle表名 as 别名 | - | - | - | - |
mysql表名 as 别名 | 支持 | × | × | - |
字段名:oracle只支持单引号;mysql只支持反单引号;(设计时考虑多数据库的关键字,避免使用)
as字段别名:oracle和mysql都支持双引号;
oracle表别名不支持as的方式, 可以去掉as,直接拼接别名;(字段别名支持as);
遇到的关键字,可以加单引号解决('as' 、'level' 、'uid'、 'display')
8、字段类型问题
CLOB、NCLOB 对应 jdcbType=“VARCHAR“ 时,插入数据没问题,但是查询数据有问题;要么把字段类型改为NVARCHAR2,要么把jdbcType改为对应数据库的类型;
BLOB字段类型表示二进制存储,一般用不到这种,可以修改为NVARCHAR2或者NCLOB或者CLOB;
关于oracle字符串类型的介绍:https://developer.aliyun.com/article/687922
常见错误日志
(以下只代表我的处理记录,仅作参考,同一个错误提示其实可能是多种结果导致的)
ORA-01465: invalid hex number
解决:BLOB类型可以改成NCLOB
ORA-00932: inconsistent datatypes: expected - got NCLOB
解决:NCLOB类型改为NVARCHAR2,或者是添加注解:
@TableField(value = "defSSOJson", jdbcType = JdbcType.NCLOB, typeHandler = NClobTypeHandler.class)
ORA-00923:FROM keyword not found where expected
解决:sql查询中字段别名有关键字,需要加双引号
ORA-00933: SQL command not properly ended
解决:
sql末尾有分号,去掉分号即可;
oracle表别名不支持as的方式, 可以去掉as,直接拼接别名;(但字段别名还是支持as的)
ORA-00911: invalid character
解决:字段的反单引号替换成单引号
SQL state [99999]; error code [17068]; Invalid argument(s) in call;
解决:升级oracle驱动包(适配oracle19c版本时报的错)
<!--oracle12c使用 12.2.0.1 -->
<!--oracla19c使用 19.3.0.0 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>${oracle.version}</version>
</dependency>
Non supported character set (add orai18n.jar in your classpath): ZHS16GBK
在本地debug启动报错如下:
java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK]
解决:添加依赖
<dependency>
<groupId>cn.easyproject</groupId>
<artifactId>orai18n</artifactId>
<version>12.1.0.2.0</version>
</dependency>
ORA-00904: "NODE_UUID": invalid identifier
解决:数据库字段缺失,少了NODE_UUID这个字段
ORA-12704: character set mismatch
解决:使用UNION时,字符集不匹配问题,字符串前面加 "N"
查询不出数据
解决:oracle不支持 <> '' 空字符串,需要使用空格来代替 <> ' '
ORA-00979: not a GROUP BY expression
oracle的order by 字段不在group by中就会报错;
Invalid column type: 1111
saveOrUpdate 中因为selectById的Id为null导致报错;但是在mysql中没问题;
解决: 修改活新增的判断改为手动判断ID是否为null,而不是selectById去查库判断;
ORA-01400: cannot insert NULL into ("ESCUSER". "PI_SS0_MOBILE_DEVICE"."ID")
解决:设置主键自增
oracle设置主键自增
-- 表名:PI_SSO_MOBILE_DEVICE
-- 主键字段:id
alter table PI_SSO_MOBILE_DEVICE add constraint id primary key (id);
-- 自定义序列名 PI_SSO_MOBILE_DEVICE_SEQ
create sequence PI_SSO_MOBILE_DEVICE_SEQ
increment by 1
start with 1
nomaxvalue
nominvalue
nocache;
create or replace trigger PI_SSO_MOBILE_DEVICE_SEQ
before insert on PI_SSO_MOBILE_DEVICE for each row
begin
select PI_SSO_MOBILE_DEVICE_SEQ.nextval into :new.id from dual;
end;
oracle修改字段类型
-- 要修改的字段名:PATH , 改为 NVARCHAR2(2000) :
-- 先添加一个PATH_NEW字段,然后把源字段值复制过来之后,
-- 再删除源字段,最后重命名一下新增的字段即可
alter table ACL_MENU add PATH_NEW NVARCHAR2(2000);
COMMENT ON COLUMN "ACL_MENU"."PATH_NEW" IS '字段描述';
update ACL_MENU set PATH_NEW=PATH;
alter table ACL_MENU drop column PATH;
alter table ACL_MENU rename column PATH_NEW to PATH;