升级JDBC驱动程序后,Postgres中对整数的隐式类型转换失败

时间:2012-12-11 19:19:43

标签: java postgresql jdbc

我的应用程序目前使用Postgres 8.2 JDBC驱动程序(使用Postgres 8.2数据库),但我们正在升级到Java 7和JDBC 4驱动程序,目前是9.2-1002版本。最终的配置是带有Postgres 8.2数据库的JDBC 9.2驱动程序。

在我们的一个触发器函数中抛出异常,并且仅在使用9.2驱动程序运行时才会发生异常。这是另一个表上的ON UPDATE触发器。触发器有效地做到了:

DECLARE
    mytime bigint;
BEGIN
    SELECT INTO mytime EXTRACT(EPOCH FROM current_timestamp(3))*1000;
    UPDATE resource SET lastmodified=mytime WHERE id=NEW.resource_id;
END

resource.lastmodified列定义为BIGINT类型。

发生的SQL错误是:

ERROR: invalid input syntax for integer: "1355248911435.9998"
    Where: PL/pgSQL function "f_modify_resource" line 4 at SQL statement;

显然错误在SELECT INTO行;这里应该有一个演员给BIGINT。但是,我想知道为什么声明成功使用8.2 JDBC驱动程序,但是当没有其他更改时,使用9.2驱动程序失败了?由于触发器代码在数据库内运行,所以这不应该对JDBC驱动程序透明吗?我认为PostgreSQL会继续在这里进行隐式转换,但似乎已经停止了。

我尝试在JDBC连接URL上设置compatible=8.2也没有效果。

修改 这是使用9.2-1002.jdbc4驱动程序运行时语句日志中的输出(我可以确认这至少发生在9.0驱动程序之前,可能更早):

STATEMENT:  UPDATE message SET hastext='true' WHERE rid='2-1355323570239' AND mid='1-1355329102968'
ERROR:  22P02: invalid input syntax for integer: "1355329102985.0002"
CONTEXT:  PL/pgSQL function "f_modify_resource" line 4 at SQL statement
LOCATION:  scanint8, int8.c:137

f_modify_resource函数由ON UPDATE表上的message触发器运行,其正文与上面给出的完全相同。第4行对应SELECT INTO语句。我可以确认EXTRACT(EPOCH...)确实返回了double precision,而且确实应该。{/ p>

使用8.2(jdbc4和jdbc3)驱动程序时,不会发生此错误,并且语句处理正确。

1 个答案:

答案 0 :(得分:1)

检查JDBC驱动程序是否正在设置* extra_float_digits *。发行说明说,从8.3-dev602开始,它在连接时设置为“2”,而通常默认为零。我无法重现你的行为(我只有9.1和9.2来测试)。但是,我可以这样做:

postgres=# set extra_float_digits = 2;
SET
postgres=# select extract(epoch from current_timestamp(3));
     date_part      
--------------------
 1355346251.7550001
(1 row)

postgres=# select extract(epoch from current_timestamp(3));
     date_part      
--------------------
 1355346253.1619999
(1 row)

当乘以1000并分配给BIGINT时,我不能让它失败,但这可能是8.2特定的,所以你必须使用9.2驱动程序进行测试并显式运行语句SET完成连接后,但在运行失败的查询之前,extra_float_digits = 0。