发现的其他改造点
1.获取当前时间
oracle:sysdate
pg:now()
2.序列
oracle: 序列名.nextval
pg:nextval(‘sequence_name’)
3.decode
oracle:decode(expr, search, result [, search, result…] [, default])
pg:CASE WHEN expr THEN expr […] ELSE expr END
4.nvl
oracle:
NVL(delete_state, ‘0’);
pg:
coalesce(delete_state, ‘0’)
其中:coalesce(expr1, expr2, expr3,…)
returns the first non-null expression that is passed to it
5.子句是否需要带别名
oracle:子句的别名并非必须
SELECT * FROM (SELECT * FROM table_a)
pg:子句必须指定别名(这种写法oracle也支持)
SELECT * FROM (SELECT * FROM table_a) AS foo
6.外关联
oracle: (+)或者left join
pg:不支持(+),请使用left join
7.嵌套语句
oracle:start with 。。。CONNECT BY
pg:with RECURSIVE ,举例:
–向下查找子节点
with RECURSIVE t(id,name,pid) as
(
select a.id,a.name,a.pid from b a where id=‘2’
union all
select k.id,k.name,k.pid from b k inner join t c on k.pid=c.id
)select id,name from t;
–向上查找父节点
with RECURSIVE t(id,name,pid) as
(
select a.id,a.name,a.pid from b a where id=‘2’
union all
select k.id,k.name,k.pid from b k inner join t c on k.id=c.pid
)select id,name from t;
8.null vs 空串
oracle:
空串==null
‘sql’||null =‘sql’
IS NULL 在oracle里,如果是null或者empty则都返回true;
pg:
空串!=null
‘sql’||null =null
is null 在pg里,如果是null,则返回true。。如果是空的,则返回false
9.update时表别名的使用
oracle: 表别名可以出现在set以及where后面,举例:
update STAFF as s1 SET s1.STAFF_STATE = 1 WHERE s1.login_name = ‘11’
pg:Update时的表别名不能出现在set 后面,可以出现在where后面
https://stackoverflow.com/questions/11369757/postgres-wont-accept-table-alias-before-column-name
错误的写法:
[SQL]update STAFF as s1 SET s1.STAFF_STATE = 1 WHERE s1.login_name = ‘11’
[Err] ERROR: column “s1” of relation “staff” does not exist
LINE 1: update STAFF as s1 SET s1.STAFF_STATE = 1 WHERE s1.login_nam…
正确的写法:
update STAFF as s1 SET STAFF_STATE = 1 WHERE s1.login_name = ‘11’ 程序中引入pg
10.数据类型与字段类型匹配严格
oracle里如果字段和值类型不匹配,比如delete_state字段是char型,delete_state=0这样并不会报错,oracle内部会对其进行转换。。但是这种情况在pg里会报错。。举例:
请注意下面这种类型转换会报错:
Delete_state是char型,正确的写法是delete_state=‘ 0’
代码改造
框架的framework_web的pom里已增加了pg的依赖
org.postgresql
postgresql
42.2.2.jre6
修改数据源(sso在jdbc.properties文件里)
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://10.45.59.178:5432/postdev
jdbc.username=postdev
jdbc.password=postdev
在properties文件里增加数据库的切换开关项
#database.Dialect database config, like: Oracle,PostgreSQL
database.Dialect=PostgreSQL
sso在sso_config.properties文件里
框架代码改造
1.mybatis 如果输入的java参数是String,实际的字段是numric,则会报错
举例:
select
ROLE_ID, NAME, STATE, STATE_DATE, EFF_DATE, EXP_DATE, TICKET_QUERY, DELETE_STATE,
DELETE_TIME, SPECIALITY_ID, ROLE_CODE
from ROLES
where ROLE_ID = #{roleId,javaType=String,jdbcType=DECIMAL}
传入的参数roleId的是String类型,而ROLE_ID字段是decimal类型。
此时会报错:operator does not exist numeric=character
解决方案:
增加了一个TypeHandler类:StringToNumericTypeHandler
import org.apache.ibatis.type.BigDecimalTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
Created by codeya on 2018/3/29.
java是String,jdbc字段是数字型的
*/
public class StringToNumericTypeHandler extends BigDecimalTypeHandler {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
throws SQLException {
if(parameter instanceof String){
// System.out.println("----------------------StringToNumeric -------------------------------------------");
ps.setBigDecimal(i, new BigDecimal(parameter.toString()));
}
else
super.setNonNullParameter(ps,i,parameter,jdbcType);
}
public Object getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return rs.getBigDecimal(columnName).toString();
}
public Object getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return cs.getBigDecimal(columnIndex).toString();
}
}
然后把此类注册(见下图),即javaType=String,JdbcType=numeric/decimal时,typeHandler采用此类。
有部分mybatis的mapper配置里,没有配置javaType,比如
#{roleId,javaType=String,jdbcType=DECIMAL},这种情况下会走到框架扩展的ResObjectTypeHandler类,为此,对此类做了改造,增加了setNonNullParameter方法