状况
Oracle 转 PostgreSQL 中踩到的坑,SQL查询结果 PL/SQL 和 pgAdmin 导出的 .csv 比较无差别(pgAdmin 导出选项可修改成和 PL/SQL 转换一致),最后集成测试时却出了类型异常。
分析
通过一番溯源,让人很无语。
SQL中有一列是 COUNT() 统计,Oracle 该列返回类型 int —— 实际是 number(38,0),而 PostgreSQL 返回的类型是 bigint;都是整数,用 csv 对比当然是无差别了。就算用第三方的数据库比较工具,直接用结果集对比,在数值相同的情况下也判断成无差别。
程序端是 Java。Oracle 返回的类型 int 即 number 对应到 Java 成了 BigDecimal;实际上因为程序针对 Oracle 开发,所有的数值都是 BigDecimal,所以程序中都是直接把数值类型的字段值按 BigDecimal 处理的
BigDecimal v = 字段值; // 无论是给变量赋值
f(字段值); // 还是传递一个 BigDecimal 类型的参数
而 PostgreSQL 返回类型 bigint 对应到 Java 成了 Long,所以无论是给变量赋值还是传参数都出错了。
解决方式
找到原因就好办了,PostgreSQL 版 SQL 在 COUNT() 后面加 ::numeric 转换类型。
感慨
程序预设立场(全是 BigDecimal)没错,但是总会冒出各种情况让你“想不到...”。
题外话
如果是 VB、VB.NET 这类具有自动隐式类型转换的语言就根本没这个问题。和数据库打交道,记录集的字段类型本来就是“随意”的。