这几天正在做数据库国产化的相关工作之前的一个项目数据库用的是oracle的现在要换成达梦的。所以我就把遇到的需要修改的列出来本篇文章持续更新中。目录1 达梦数据库中会出现多余的0占位2 order by 排序的时候会把null空值排前面3 is null,is not null与空字符不兼容4 达梦数据库查询语句严格区分字符串尾部空格问题5 oracle有自动收集统计信息的定时任务而达梦需要自己去弄个定时任务6 oracle和达梦date数据类型区别1 达梦数据库中会出现多余的0占位无论是oracle还是达梦数据库都有number类型格式都为number(m,n)。两个数据库中有相同的表由于业务需求我不能将原表的相关表的表结构晒出现将测试表的结构展示如下CREATE TABLE CESHI (ID VARCHAR2(50) DEFAULT SYS_GUID() NOT NULL,NAME VARCHAR2(50) NULL,ADDRESS VARCHAR2(50) NULL,COLUMN1 VARCHAR2(70) NULL,TOTAL NUMBER(15,3) NULL,CONSTRAINT CESHI_PK PRIMARY KEY (ID));达梦数据库的数据如下oracle数据库如下java端用的是springboot加mybatis代码如下package boke.hbc.dingshiqi.ceshi; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; RequestMapping(/ceshi) RestController public class CeshiController { Autowired private CeshiService service; RequestMapping(value /dmandorcl) public JSONObject dmandorcl() { ListMap list1service.dmandorcl(); for(Map map1:list1) { System.out.println(map1.toString()); } JSONObject resultjsonnew JSONObject(); resultjson.put(code, 0); return resultjson; } }service:package boke.hbc.dingshiqi.ceshi; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSONObject; Service public class CeshiService { Autowired CeshiMapper mapper; public ListMap dmandorcl() { // TODO Auto-generated method stub return mapper.dmandorcl(); } }mapperpackage boke.hbc.dingshiqi.ceshi; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; Mapper public interface CeshiMapper { Select(select * from ceshi) ListMap dmandorcl(); }在oracle数据库的情况下控制台显示如下{TOTAL777, ADDRESSnull, ID22222, COLUMN1null, NAMEnull}{TOTAL444.745, ADDRESSz, ID2F172A78A876449F8B267927741774FB, COLUMN1null, NAMEssss}{TOTAL111, ADDRESSddd, IDAB26EE87BFFF4ED7B4A666FBCAF357CC, COLUMN1null, NAMEssssf}在dameng数据库环境下控制台显示如下{TOTAL22.000, ADDRESSnull, ID22222, COLUMN1null, NAMEnull}{TOTAL344.000, ADDRESSz, ID2F172A78A876449F8B267927741774FB, COLUMN1null, NAMEssss}{TOTAL22.870, ADDRESSddd, IDAB26EE87BFFF4ED7B4A666FBCAF357CC, COLUMN1null, NAMEssssf}这种小数点后三个0的情况输入到前端页面显然是不合适的所以我做了个拦截器代码如下package com.bocomsoft.util; import java.math.BigDecimal; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; import org.apache.ibatis.type.MappedTypes; MappedJdbcTypes({JdbcType.NUMERIC,JdbcType.DECIMAL}) MappedTypes(BigDecimal.class) public class BigDecimalTypeHandler extends BaseTypeHandlerString { Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { // TODO Auto-generated method stub System.out.println(iiparameterparameterjdbcTypejdbcType.toString()); ps.setString(i, parameter); } Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { // TODO Auto-generated method stub //System.out.println(哈哈1columnName); BigDecimal val rs.getBigDecimal(columnName); if(val!null) { String val2val.toPlainString(); if (val2.indexOf(.) 0) { // 去掉多余的0 val2 val2.replaceAll(0?$, ); // 如果最后一位是. 则去掉 val2 val2.replaceAll([.]$, ); } return val2; }else { return ; } } Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { // TODO Auto-generated method stub //System.out.println(哈哈2); BigDecimal val rs.getBigDecimal(columnIndex); if(val!null) { String val2val.toPlainString(); if (val2.indexOf(.) 0) { // 去掉多余的0 val2 val2.replaceAll(0?$, ); // 如果最后一位是. 则去掉 val2 val2.replaceAll([.]$, ); } return val2; }else { return ; } } Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { // TODO Auto-generated method stub //System.out.println(哈哈3); BigDecimal val cs.getBigDecimal(columnIndex); if(val!null) { String val2val.toPlainString(); if (val2.indexOf(.) 0) { // 去掉多余的0 val2 val2.replaceAll(0?$, ); // 如果最后一位是. 则去掉 val2 val2.replaceAll([.]$, ); } return val2; }else { return ; } } }这样输出的结果就不带有多余的0了2 order by 排序的时候会把null空值排前面在oracle中select语句如果涉及到排序默认的情况是把排序字段中为null的值排后而达梦数据库正好相反还是看那个ceshi表两个数据库执行同样的sql语句SELECT * FROM ceshi t ORDER BY t.ADDRESSoracle的执行结果如下所示而达梦数据库则变成这个样子了如果要做数据库适配的话一定要注意。3 is null,is not null与空字符不兼容在oracle中如果一个字段的值是空字符得话他与null是等价的我们可以用is null或is not null进行判断但是达梦有可能是不一样空字符和null不是等价的。主要与数据库设置有关这个参数叫COMPATIBLE_MODE具体参考链接如下所示达梦数据库非空约束错误解决明明插入空字符串但还是触发非空约束_达梦数据库违反列非空约束-CSDN博客4 达梦数据库查询语句严格区分字符串尾部空格问题在oracle数据库中是严格区分a和a 的但是在达梦数据库中是有可能不区分的可数据库的BLANK_PAD_MODE参数当BLANK_PAD_MODE0时除去group by 这种分组操作时严格区分外其他比较、count等操作不严格区分a和a 认为这两个字符串是相等的。而且比较坑的是数据库实例已经建立的情况下他是不能改的除非重装数据库╯‵□′╯︵┴─┴ 掀桌补救的措施是修改SPACE_COMPARE_MODE参数然后重启服务器右空格可以这么解决左空格自求多福吧我当时找的参考链接如下达梦数据库查询语句严格区分字符串尾部空格问题_达梦数据库空格填充模式-CSDN博客5 oracle有自动收集统计信息的定时任务而达梦需要自己去弄个定时任务这个问题我当时是这么发现的当时我们达梦上的测试库和正式库的数据量差不多然后我就发现正式库查询特别慢我就问达梦数据库的售后咋回事他调了半天说oracle默认的情况下有自动收集统计信息的定时任务当高于一个阈值的时候他会自动进行收集统计信息。达梦需要自己弄后来我在网上看到说达梦也可以进行设定但是我没时间以后去验证一下吧他就用sysdba用户加了个定时任务里面执行的sql脚本为CALL DBMS_STATS.GATHER_SCHEMA_STATS(大写的用户名,100,TRUE,FOR ALL COLUMNS SIZE AUTO)每两天执行一次参考链接如下达梦数据库如何收集统计信息_达梦收集统计信息-CSDN博客6 oracle和达梦date数据类型区别oracle和达梦都有date数据类型但oracle是精确到秒达梦只能精确到天默认值都可以用sysdate,所以如果达梦想要精确到秒数据类型应该使用TIMESTAMP,在日期计算上也是有区别的总结如下在达梦数据库中SYSDATE 1表示当前系统时间往后推 1 天即 24 小时。运算单位达梦日期运算以“天”为基本单位整数1代表 1 天 。语法示例SELECT SYSDATE 1 FROM DUAL;返回明天的日期时间。其他精度若需计算小时或分钟需转换为天数如加 5 小时写作SYSDATE 5.0/24。