Получение последовательности из SQL INSERT с JDBC

Поэтому я пытаюсь добавить в базу данных с помощью JDBC из файлов. И теперь, когда INSERTING, мне нужно получить ID перед вставкой, и было бы лучше, если бы база данных по-прежнему использовала sequence.

В папке resources у меня есть файл insert_plant.sql, содержащий этот запрос:

INSERT INTO PLANTS (id, plantname, species)
  VALUES (NEXT VALUE FOR sequence, ?, null);

И таблица создается с этим:

DROP SCHEMA public CASCADE;

CREATE SEQUENCE sequence START WITH 1;

CREATE TABLE PLANTS (
   id BIGINT NOT NULL PRIMARY KEY,
   plantname VARCHAR(255) NOT NULL,
   species VARCHAR(255) NULL,
);

А теперь на Java я вызываю это:

public static void insertIntoOrderTable(BasicDataSource basicDataSource, String plantname) throws  SQLException{
    Connection conn = null;
    PreparedStatement stmt = null;

    try {
        conn = basicDataSource.getConnection();
        stmt = conn.prepareStatement(Util.readFileFromClasspath("insert_plant.sql"));
        stmt.setString(1, plantname);
        stmt.executeUpdate();

        //Below is the line 57 (in error)
        ResultSet rs = stmt.executeQuery("SELECT sequence.NEXTVAL FROM PLANTS");
        if (rs.next()){
            System.out.println("ID" + rs.getInt(1));
        }

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        if (stmt != null) {
            stmt.close();
        }
        if (conn != null) {
            conn.close();
        }
    }
}

И я получаю ошибку:

java.sql.SQLFeatureNotSupportedException: feature not supported
at org.hsqldb.jdbc.JDBCUtil.notSupported(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeQuery(Unknown Source)
at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
at database.PlantDao.insertIntoOrderTable(PlantDao.java:57)
at database.PlantDao.main(PlantDao.java:19)

Итак, вопрос

Какую СУБД вы используете?

Andrew 15.10.2018 16:36

Вероятно, это не источник вашей проблемы, но не рекомендуется использовать зарезервированные ключевые слова для имен переменных, называя в этом случае последовательность вашей последовательности.

StephaneM 15.10.2018 16:37

@StephaneM, я просто положил это сюда, чтобы было понятнее

Richard 15.10.2018 16:42

@Andrew Я использую hsqldb

Richard 15.10.2018 16:44

Я думаю, что для H2 используется синтаксис NEXTVAL('SequenceName').

Andrew 15.10.2018 16:44

Вам не нужно выполнять второй оператор для получения значения id. Сразу после первого stmt.executeUpdate() вы можете получить сгенерированные ключи с помощью метода docs.oracle.com/javase/7/docs/api/java/sql/….

The Impaler 15.10.2018 16:45

@TheImpaler как именно я могу это получить .. я не совсем понял

Richard 15.10.2018 17:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
1 046
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как уже прокомментировал «The Impaler», нет необходимости выполнять второй оператор, с JDBC вы можете использовать

PreparedStatement stmt = conn.prepareStatement(sql, new String[]{"id"});

И чтобы извлечь из этого пользу:

ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()){
    System.out.println(rs.getLong(1));
}

Итак, ваш метод будет выглядеть примерно так:

public static void insertIntoOrderTable(BasicDataSource basicDataSource, String plantname) throws  SQLException{
    Connection conn = null;
    PreparedStatement stmt = null;

    try {
        conn = basicDataSource.getConnection();
        stmt = conn.prepareStatement(Util.readFileFromClasspath("insert_plant.sql"), new String[]{"id"});
        stmt.setString(1, plantname);
        stmt.executeUpdate();

        ResultSet rs = stmt.getGeneratedKeys();
        if (rs.next()){
            System.out.println(rs.getLong(1));
        }

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        if (stmt != null) {
            stmt.close();
        }
        if (conn != null) {
            conn.close();
        }
    }
}

Другие вопросы по теме