Подтвердить что ты не робот

Postgres JDBC-драйвер: PSQLException: синтаксическая ошибка при или около RETURNING

По какой-то причине драйвер JDBC PostgreSQL добавляет: RETURNING * в конец операторов выбора. Зачем?

Код:

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);

Исключение:

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)

Источник данных (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>

Версия драйвера PostgreSQL JDBC

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

Захват пакета

https://postimg.cc/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
4b9b3361

Ответ 1

Это выглядит как проблема с sql2o. В комментариях к отчету об ошибке говорится:

Утилизация с использованием PostgreSQL, все инструкции SELECT будут сгенерированы с сообщением: org.postgresql.util.PSQLException: ОШИБКА: ошибка синтаксиса в точке или рядом "ВОЗВРАЩЕНИЕ"

Кажется, он связан с этой проблемой

Это исправлено с версией 1.1.2.

Для исправления требуется, чтобы флаг перечисления QuirkMode устанавливался в PostgreSQL, когда создавая новый экземпляр sql2o. Он изменяет поведение по умолчанию Запросы НЕ ПОЛУЧИТЬ сгенерированные ключи по умолчанию. Когда это необходимо для fetch сгенерированные ключи, параметр returnGeneratedKeys в Метод generateQuery должен быть установлен.

Так как Sql2o 1.6.0, включите зависимость sql2o-postgres и используйте new PostgresQuirks() вместо QuirksMode.

Ответ 2

Самый простой способ, которым я это сделал, - добавить "; -" в конец кода 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();

Ответ 3

В моем случае произошло, когда вы пытались вставить пустой список объектов.