2

私のアプリケーションは現在 Postgres 8.2 JDBC ドライバー (Postgres 8.2 データベースを使用) を使用していますが、現在 9.2-1002 リリースである Java 7 と JDBC 4 ドライバーにアップグレードしています。最終的な構成は、Postgres 8.2 データベースを使用する JDBC 9.2 ドライバーです。

トリガー関数の 1 つでスローされる例外があり、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 はここで引き続き暗黙のキャストを行うと思っていましたが、停止しているようです。

compatible=8.2JDBC接続URLを設定してみましたが、効果もありません。

編集 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 UPDATEmessage行 4 はSELECT INTOステートメントに対応します。EXTRACT(EPOCH...)が実際に を返すことを確認できますdouble precision

8.2 (jdbc4 および jdbc3) ドライバーでは、このエラーは発生せず、ステートメントは正しく処理されます。

4

1 に答える 1

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 を明示的に実行してテストする必要があります。接続が完了した後、失敗したクエリを実行する前。

于 2012-12-12T21:09:12.487 に答える