最近公司公司项目为支持oralce数据库,我们对项目进行移植,项目中使用 MyBatis需要手工对 MyBatis sql xml文件进行修改,修改过程中遇到不少问题,记录在此方便后续查看。
数据类型错误 ORA-00932
SELECT DISTINCT sg.ID, sg.CODE, sg.NAME, sg.ORGANIZATION_ID, sg.DESCRIPTION, -- to_char(sg.DESCRIPTION), sg.SORT, sg.CREATE_USER, FROM SYS_GROUP sg
原因:DESCRIPTION字段类型为NCLOB,而DISTINCT不支持对NCLOB类型字段进行操作,使用to_char函数进行转换即可
ora-02290 违反检查约束条件
此条错误出现在执行一条新增SQL语句时,检查半天后未发现有什么异常,该语句在MYSQL也能够正常执行,后来查询资料了解到可以查询视图CONSTRAINT_NAME进行检查。
select * from dba_constraints where CONSTRAINT_NAME like '%89071';
仔细查询之后发现出现此原因情况是表字段缺少,MYSQL环境下该表某个字段设置有默认值,但移植到ORACLE环境下未对该字段设置默认值,同时SQL语句中也未申明该字段于是出现这种错误。
在修改SQL后,在PL/SQL中能够正常执行语句,但通过程序执行后出现如下错误:
org.springframework.jdbc.UncategorizedSQLException: Error setting null for parameter #6 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型
这种错误出现之前也有遇到过,是当字段为NULL时,未指定jdbcType类型的参数就可能导致此问题,之前执行insert语句时我都会添加,现在是移植就通过添加jdbcType来修改,jdbcType必须为为ibatis的申明enum类型,否则也会出现异常,默认包含以下类型:
package org.apache.ibatis.type; public enum JdbcType { ARRAY, BIT, TINYINT, SMALLINT, INTEGER, BIGINT, FLOAT, REAL, DOUBLE, NUMERIC, DECIMAL, CHAR, VARCHAR, LONGVARCHAR, DATE, TIME, TIMESTAMP, BINARY, VARBINARY, LONGVARBINARY, NULL, OTHER, BLOB, CLOB, BOOLEAN, CURSOR, UNDEFINED, NVARCHAR, NCHAR, NCLOB, STRUCT;
ORA-00984: 列在此处不允许 修改后再次执行SQL依然提示出错
再次检查后发现SQL语句中values中写死一个”1“,尝试去掉双引号为单引号能够正常执行,确定是因为双引号引起,之前在MYSQL中用双引号于单引号还未出现此情况。
还有一种情况列名添加单引号也会引起ORALCE报错,在MYSQL中写SQL语句时有时会帮列名添加单引号,但在ORALCE中不允许此种写法。
列名小写 执行一个SQL时出现空指针异常,检查发现是获取ID时,是通过KEY 小写的id进行获取,但查询结果集中为大写的ID,检查SLQ后发现通过as进行别名添加,但是输出的结果仍都为大写,通过添加双引号对别名进行处理 后能够输出小写,必须为双引号单引号会出错。
select sysdate as "date" from dual
ORACLE 获取自增长ID
MYSQL中可以通过两种方式获取执行INSERT语句时获取自增长的ID。
方式1:
<insert id="save" useGeneratedKeys="true" keyProperty="id" parameterType="Record">
方式2:
<insert id="save" useGeneratedKeys="true" keyProperty="id" <selectKey resultType="int" keyProperty="id" order="AFTER"> SELECT LAST_INSERT_ID() AS id </selectKey>
在ORACLE中通过这两方式进行插入都不行,在使用方式2进行处理时会抛出错误:
ORA-00923: 未找到要求的 FROM 关键字
我猜想问题就出在
SELECT LAST_INSERT_ID() AS id
这句,在MYBAITES在ORALCE中无法执行这个语句,在MYSQL中可以使用
我修改成为下面的方式就能够成功处理,通过查询下个SEQ来获取ID
<insert id="save" parameterType="hashMap" useGeneratedKeys="true" > <selectKey keyProperty="roleId" resultType="int" order="BEFORE"> SELECT SEQ_SYS_ROLE.NEXTVAL FROM DUAL </selectKey>
同时需要注意在修改成这种方式时不能够在INSERT标签中申明
keyProperty="id"
如果申明,则返回的ID数据将不正确,同事在执行这个语句的时候发现返回的数据并非INT类型的ID,而返回了一个BYTE数 组。
当使用自定义对象进行新增时,ID如果为Integer类型的来接收返回的ID就会出现错误(使用int类型不会报错)
java.sql.SQLException: 无效的列类型: getInt not implemented for class oracle.jdbc.driver.T4CRowidAccessor
可以在对象中添加另外一个String类型的字段,在执行INSERT语句时用该字段保存返回的ID,最后在该字段的set方法中赋值给ID,方法虽然麻烦了点,但是了减少改动只能使用这种方式。
ORA-00904: "TYPE": 标识符无效
在一张表中某列名为”TYPE“,出现该问题时起初以为是因为使用了ORALCE关键字,之前此类问题在关键字上面添加双引号都能够解决此问题,添加后发现仍出现此问题,检查数据库表后发现列名为小写的“type”,确定是因为通过工具直接导出的脚本建表语句中为该字段添加了双引号导致,如出现该问题请首先检查数据库字段是否一致。