2014-07-08 12 views
11

Per qualche motivo il driver JDBC PostgresSQL sta aggiungendo: RESTITUZIONE * alla fine delle istruzioni di selezione. Qualcuno ha qualche idea del perché?Postgres JDBC driver: PSQLException: errore di sintassi in corrispondenza o vicino RESTITUZIONE

Codice:

protected static final String AUTH_QUERY = "SELECT \"SECRET\" FROM \"user\" WHERE \"NAME\" = :name"; 

String password = sql2o.open().createQuery(AUTH_QUERY).addParameter("name", username).executeScalar(String.class); 

Eccezione:

org.postgresql.util.PSQLException: ERROR: syntax error at or near "RETURNING" 
    Position: 47 
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2161) 
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1890) 
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:559) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:302) 
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76) 
    at org.sql2o.Query.executeScalar(Query.java:533) 
    at org.sql2o.Query.executeScalar(Query.java:577) 
    at org.sql2o.Query.executeScalar(Query.java:568) 

La fonte dei dati (JNDI):

<Configure id="wac" class="org.eclipse.jetty.webapp.WebAppContext"> 

    <New id="mydb" class="org.eclipse.jetty.plus.jndi.Resource"> 
     <Arg></Arg> 
     <Arg>jdbc/mydb</Arg> 
     <Arg> 
      <New class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
       <Set name="driverClass">org.postgresql.Driver</Set> 
       <Set name="jdbcUrl">jdbc:postgresql://localhost:5432/mydb</Set> 
       <Set name="user">user</Set> 
       <Set name="password">pass</Set> 
      </New> 
     </Arg> 
    </New> 
</Configure> 

del driver JDBC PostgreSQL versione

<dependency> 
    <groupId>org.postgresql</groupId> 
    <artifactId>postgresql</artifactId> 
    <version>9.3-1101-jdbc41</version> 
</dependency> 

cattura dei pacchetti

http://postimg.org/image/gbl2dq4zx/

No.  Time   Source    Destination   Protocol Length Info 
    12 0.175636000 127.0.0.1    127.0.0.1    PGSQL 182 >P/B/D/E/S 

Frame 12: 182 bytes on wire (1456 bits), 182 bytes captured (1456 bits) on interface 0 
PostgreSQL 
    Type: Parse 
    Length: 69 
    Statement: 
    Query: SELECT "SECRET" FROM "user" WHERE "NAME" = $1 RETURNING * 
    Parameters: 1 
     Type OID: 1043 
+0

https://github.com/pgjdbc/pgjdbc/blob/master/org/ postgresql/jdbc3/AbstractJdbc3Statement.java/line 148 – tty

risposta

8

Questo appare come un problem with sql2o. Le osservazioni sulla relazione bug dicono:

Whe using PostgreSQL, all SELECT statements will fail with message: org.postgresql.util.PSQLException: ERROR: syntax error at or near "RETURNING"

Seems to be related to this issue

This has been fixed with version 1.1.2.

The fix requires the QuirkMode enum flag to be set to PostgreSQL when creating a new instance of sql2o. It changes default behaviour of queries to NOT fetch generated keys by default. When it is needed to fetch generated keys, the returnGeneratedKeys parameter in the generateQuery method should be set.

Dal Sql2o 1.6.0, includono la dipendenza sql2o-Postgres e utilizzare new PostgresQuirks() invece di QuirksMode.

+1

Grazie 'nuovo Sql2o (dataSource, QuirksMode.PostgreSQL)' risolto il mio problema – tty

+0

Da Sql2o 1.6.0, è necessario includere la dipendenza 'sql2o-postgres' e usare' new PostgresQuirks() 'invece di' QuirksMode'. – Zout

+0

@Zout: grazie, compreso quello nella risposta. –

9

Il modo più semplice che ho fatto questo è stato l'aggiunta "; -" alla fine del codice SQL:

String sql = "INSERT INTO testTable(var1, var2) values ("1","2"), ("1","2") RETURNING id;--"; 

PreparedStatement ps = getConnection().prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 
ps.executeUpdate(); 
ResultSet rs = ps.getGeneratedKeys(); 
+0

soluzione impressionante :) –

+0

Perché funziona? – cdmckay

+1

Poiché PreparedStatement aggiunge qualcosa alla fine e interrompe l'opzione di restituzione. Se vuoi vedere cosa succede esattamente dovresti eseguire il debug delle tue richieste nel database .. – Ariloum

Problemi correlati