2016-05-06 11 views
1

Wie kann ich Double.NaN in ein PostgreSQL-Feld mit doppelter Genauigkeit mit JOOQ einfügen?Einfügen von NaN-Werten in Postgresql-Datenbank mit JOOQ

Ich benutze PostgreSQL 9.5 mit JOOQ 3.7.3. Ich füge Sensorwerte im Batch in eine Tabelle ein. Manchmal ist der Wert ein NaN, und wenn JOOQ versucht, es einzufügen, löst es eine Ausnahme aus.

org.springframework.jdbc.BadSqlGrammarException: jOOQ; bad SQL grammar []; 
nested exception is java.sql.BatchUpdateException: Batch entry 6 
insert into "sensordata" ("measure_time", "location_id", "sensor_id", "value") 
values (1462551000, 12, 15, NaN) 
on conflict ("measure_time", "location_id", "sensor_id") 
do update set "value" = NaN 
was aborted. 
Call getNextException to see the cause. 
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:99) ~[spring-jdbc-4.2.5.RELEASE.jar:4.2.5.RELEASE] 
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.2.5.RELEASE.jar:4.2.5.RELEASE] 
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.5.RELEASE.jar:4.2.5.RELEASE] 
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.5.RELEASE.jar:4.2.5.RELEASE] 

Das Wertfeld in SQL als solche definiert: "value" DOUBLE PRECISION NOT NULL DEFAULT 0.0

Der relevante Teil meiner Java-Code:

final List<InsertOnDuplicateSetMoreStep<SensordataRecord>> inserts = 
seq(list) 
.map(this::process) 
.flatMap(t -> t) 
.map(d -> 
    sql.insertInto(SENSORDATA, SENSORDATA.MEASURE_TIME, SENSORDATA.LOCATION_ID, SENSORDATA.SENSOR_ID, SENSORDATA.VALUE) 
     .values(d.getMeasureTime(), d.getLocationId(), d.getSensorId(), d.getValue()) 
     .onDuplicateKeyUpdate() 
     .set(SENSORDATA.VALUE, d.getValue()) 
    ) 
    .toList(); 
sql.transaction(cfg -> DSL.using(cfg).batch(inserts).execute()); 
+0

Das Problem ist mit der Stapeleinfügung, nachdem ich es mit 'inserts.forEach (Abfrage -> DSL.using (cfg) .execute (query));' Die Transaktion läuft gut. Vielleicht sollte ich die Frage zu ändern: "Warum schlägt Stapeleinfügung bei Verwendung der onDuplicateKeyUpdate-Klausel fehl?", Aber ich bin nicht sicher, ob das das echte Problem mit meiner Abfrage ist. – kazmer

Antwort

0

einen Fehler in jOOQ Dies ist: https://github.com/jOOQ/jOOQ/issues/5249

jOOQ sollte NaN als 'NaN'::double precision explizit in double precision. Es gibt zwei mögliche Abhilfen für Sie:

In diesem speziellen Fall, letzteres wahrscheinlich preferrable ist, wie Sie viel bekommen bessere Leistung durch die Feinabstimmung von Bulk-, Batch- und Commit-Größen.

+0

Es sieht so aus, als ob die einzige Möglichkeit darin besteht, das Casting mit expliziter NaN-Prüfung zu implementieren. Die einzelne Anweisung mit mehreren Bindevariablen funktioniert nicht, weil ich auch die onDuplicateKeyUpdate-Klausel brauche. – kazmer