10

From Java, I'm calling a prepared statement in Postgresql with an insert that has a RETURNING clause for my identity column. In PG admin it comes right back, but not sure how to get it from my prepared statement:

        String insertStatement = "INSERT INTO person(\n" +
                "            name, address, phone, customer_type, \n" +
                "            start_dtm)\n" +
                "    VALUES (?, ?, ?, ?, \n" +
                "            ?)\n" +
                "    RETURNING person_id;";


        PreparedStatement stmt = connection.prepareStatement(insertStatement);

        stmt.setObject(1, perToSave.getName(null));
        stmt.setObject(2, editToSave.getAddress());
        stmt.setObject(3, editToSave.getPhone());
        stmt.setObject(4, editToSave.getCustType());
        long epochTime = java.lang.System.currentTimeMillis();
        stmt.setObject(5, new java.sql.Date(epochTime));

        stmt.executeUpdate();

4 Answers 4

25

I do not have enough reputation to Comment and my Edit got rejected, so sorry for re-posting the already accepted answer from hd1.

executeUpdate expects no returns; use execute. Check if there is some results before trying to retrieve the value.

String insertStatement = "INSERT INTO person(\n" +
                "            name, address, phone, customer_type, \n" +
                "            start_dtm)\n" +
                "    VALUES (?, ?, ?, ?, \n" +
                "            ?)\n" +
                "    RETURNING person_id;";

PreparedStatement stmt = connection.prepareStatement(insertStatement);

stmt.setObject(1, perToSave.getName(null));
stmt.setObject(2, editToSave.getAddress());
stmt.setObject(3, editToSave.getPhone());
stmt.setObject(4, editToSave.getCustType());
long epochTime = java.lang.System.currentTimeMillis();
stmt.setObject(5, new java.sql.Date(epochTime));

stmt.execute();
ResultSet last_updated_person = stmt.getResultSet();
if(last_updated_person.next()) {
   int last_updated_person_id = last_updated_person.getInt(1);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Posting your own answer that completes another user's answer is OK as long as you provide credit (which you did) - see meta.stackoverflow.com/a/338292/5375403 It would be a good idea though if you stated clearly how your answer differs from the original one, and why it does so.
6

According to the javadoc, PreparedStatement inherits from Statement and the latter contains a getResultSet() method. In other words, try this:

String insertStatement = "INSERT INTO person(\n" +
                "            name, address, phone, customer_type, \n" +
                "            start_dtm)\n" +
                "    VALUES (?, ?, ?, ?, \n" +
                "            ?)\n" +
                "    RETURNING person_id;";


PreparedStatement stmt = connection.prepareStatement(insertStatement);

stmt.setObject(1, perToSave.getName(null));
stmt.setObject(2, editToSave.getAddress());
stmt.setObject(3, editToSave.getPhone());
stmt.setObject(4, editToSave.getCustType());
long epochTime = java.lang.System.currentTimeMillis();
stmt.setObject(5, new java.sql.Date(epochTime));

stmt.execute();
ResultSet last_updated_person = stmt.getResultSet();
last_updated_person.next();
int last_updated_person_id = last_updated_person.getInt(1);

Leave a comment if you have further issues.

3 Comments

executeUpdate() throws a "org.postgresql.util.PSQLException: A result was returned when none was expected. " as it's not supposed to see a result returned. also getresultSet() without a next call throughs : org.postgresql.util.PSQLException: ResultSet not positioned properly, perhaps you need to call next.
This answer uses "executeUpdate", but the correct method to call is "execute", as shown in the highly-upvoted, unaccepted answer. Copy and paste from the next answer :-)
this is not a correct answer. Correct upvoted but mistakingly unaccepted answer is below
4

Calling executeUpdate() expects no result from statement. Call stmt.execute() and then stmt.getResultSet()

Comments

3

JDBC has built-in support for returning primary key values for insert statements. Remove the "returning" clause from your SQL and specify PreparedStatement.RETURN_GENERATED_KEYS as a second parameter to your prepareStatment(...) call. Then you can get the generated primary key by calling stmt.getGeneratedKeys() on your PreparedStatement object after calling executeUpdate().

String insertStatement = "INSERT INTO person(\n" +
    "            name, address, phone, customer_type, \n" +
    "            start_dtm)\n" +
    "    VALUES (?, ?, ?, ?, \n" +
    "            ?)";

PreparedStatement stmt = connection.prepareStatement(insertStatement,
    PreparedStatement.RETURN_GENERATED_KEYS);

stmt.setObject(1, perToSave.getName(null));
stmt.setObject(2, editToSave.getAddress());
stmt.setObject(3, editToSave.getPhone());
stmt.setObject(4, editToSave.getCustType());
long epochTime = java.lang.System.currentTimeMillis();
stmt.setObject(5, new java.sql.Date(epochTime));

stmt.executeUpdate();
    
ResultSet resultSet = stmt.getGeneratedKeys();
resultSet.next();
int lastInsertedPersonID = resultSet.getInt(1);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.