How to get the id of last inserted row using preparedstatement? [duplicate] - java

This question already has answers here:
How to get a value from the last inserted row? [duplicate]
(14 answers)
Closed 9 years ago.
I am using the following code to insert a new row to database, I need to get the id of the last inserted row but when I run the code it shows the following message:
SEVERE: java.sql.SQLException: Generated keys not requested. You need to specify
Statement.RETURN_GENERATED_KEYS to Statement.executeUpdate() or
Connection.prepareStatement().
When I use the following code also it gives error although I choose executeUpdate(String sql)
ps.executeUpdate(ps.RETURN_GENERATED_KEYS);
error >> no suitable method found for executeUpdate(int)
the table is as following:
credential
int ID primary key, auto increment
varchar(10) name
my code
String Insert_Credential = "Insert into credential values("
+ "?,?)";
ps = con.prepareStatement(Insert_Credential);
ps.setInt(1, 0);
ps.setString(2, "username");
ps.executeUpdate();
ResultSet generatedKeys = ps.getGeneratedKeys();
if (generatedKeys.next()) {
System.out.println("id is"+generatedKeys.getLong(1));
return generatedKeys.getInt(1);
} else {
throw new SQLException("Creating user failed, no generated key obtained.");
}

ps.executeUpdate(ps.RETURN_GENERATED_KEYS)
You invented that. It doesn't exist.
ps = con.prepareStatement(Insert_Credential);
That doesn't tell the PreparedStatement to return generated keys either. You need this:
ps = con.prepareStatement(Insert_Credential, Statement.RETURN_GENERATED_KEYS);

Related

java.sql.SQLException: Closed Resultset: next [duplicate]

This question already has an answer here:
SQLException: the result set is closed
(1 answer)
Closed 3 years ago.
I didn't find the reason for a SQLExeption, I got it at while(dbrs.next()). It is simple, it was working, but after update to Oracle Server 19, I got this error. I got still a result set in Oracle Developer with the same account.
Statement st = conn.createStatement();
if (Oracle){
ResultSet dbrs = st.executeQuery("select table_name from all_tables");
while(dbrs.next()){
if (dbrs.getString(1).equals(G_IN)){
st.execute("DROP TABLE "+G_IN);
System.out.println(G_IN+" gelöscht");
}
}
dbrs.close();
}else{
String loeschen="DROP TABLE IF EXISTS \"" + G_IN +"\"";
System.out.println(loeschen);
st.execute( loeschen );
}
You shouldn't reuse a Statement object as is the case in your while loop. To execute a new query, you need to use a new Statement object.
Replace
st.execute("DROP TABLE "+G_IN);
with
conn.createStatement().execute("DROP TABLE "+G_IN);
and it should work.

getting the result of sql command in java [duplicate]

This question already has an answer here:
java.sql.sqlexception column not found
(1 answer)
Closed 4 years ago.
i need to get the last id entered in my data base witch is AUTO_INCREMENT so i did this
String Var = "SELECT MAX(id) FROM goupe ; ";
ResultSet vari=st.executeQuery(Var);
while(vari.next()){
nombre = vari.getInt("id");}
String sql = "INSERT INTO Student(name,famillyname,email,password,module,speciality,card,id_goupe)VALUES('"+name+"','"+familly+"','"+email+"','"+pass+"','"+module+"','"+specialite+"','"+card+"','"+nombre+"');";
st.execute(sql);
but i had this problem Column 'id' not found.
so what should i do to have it right .
I have to say, there are a couple of really easy things you can do to greatly improve your code.
If your latest ID is generated elsewhere, then embed the query directly into the statement such that you don't need to go get it. That will reduce the risk of a race condition.
Use PreparedStatements. Let me ask you this question: What do you suppose is going to happen if one of your user's name is O'Ryan?
Since your code is just a snip, I also will only provide a snip:
int index = 1;
String sql = "INSERT INTO Student(name,famillyname,email,password,module,speciality,card,id_goupe)" +
"VALUES(?,?,?,?,?,?,?,(SELECT MAX(id) FROM goupe));";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(index++, name);
ps.setString(index++, familyname);
ps.setString(index++, email);
ps.setString(index++, password);
ps.setString(index++, module);
ps.setString(index++, speciality);
ps.setString(index++, card);
int rows = ps.executeUpdate();
if(rows == 1) {
System.out.println("Successfully inserted row");
}
When you execute the query SELECT MAX(id) FROM goupe;, then in the returned table, the column name no longer remains as id.
So, the best approach is to provide a name for the column like below:
SELECT MAX(id) AS maxid FROM goupe;
Then, you can get the value using:
vari.getInt("maxid")

Retrieving the last inserted Identity ID from a table using the Statement.RETURN_GENERATED_KEYS routine? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to get the insert ID in JDBC?
In the following statement, how can I fetch the last inserted C12 identity value? This is from the JavaDB manual, but they have not mentioned how to retrieve this last inserted value from this record set.
CREATE TABLE TABLE1 (C11 int, C12 int GENERATED ALWAYS AS IDENTITY)
Statement stmt = conn.createStatement();
stmt.execute(
"INSERT INTO TABLE1 (C11) VALUES (1)",
Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
Here's an example to get generated keys:
ResultSet rs = statement.getGeneratedKeys();
if (rs != null && rs.next()) {
key = rs.getLong(1);
}
PS: A related StackOverflow question can suffice.

SQL (Java, h2): What's the best way to retrieve the unique ID of the single item I just inserted into my database? [duplicate]

This question already has answers here:
How to get the insert ID in JDBC?
(14 answers)
Closed 7 years ago.
My current method is this:
SELECT TOP 1 ID FROM DATAENTRY ORDER BY ID DESC
This assumes the latest inserted item always has the highest unique ID (primary key, autoincrementing). Something smells wrong here.
Alternatives?
If the JDBC driver supports it, you can also just use Statement#getGeneratedKeys() for that.
String sql = "INSERT INTO tbl (col) VALUES (?)";
preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
preparedStatement.setString(1, col);
preparedStatement.executeUpdate();
generatedKeys = preparedStatement.getGeneratedKeys();
if (generatedKeys.next()) {
long id = generatedKeys.getLong(1);
} else {
// Throw exception?
}
If using MySQL you can do
select last_insert_id();
If using MS SQL
select scope_identity();
For H2, I believe it's
CALL SCOPE_IDENTITY();
but I don't have any experience with that DB

Value from last inserted row in DB [duplicate]

This question already has answers here:
How to get a value from the last inserted row? [duplicate]
(14 answers)
Closed 9 years ago.
Is there some way to get a value from the last inserted row?
I am inserting a row where the PK will automatically increase due to sequence created, and I would like to get this sequence number. Only the PK is guaranteed to be unique in the table.
I am using Java with a JDBC and Oracle.
I forgot to add that I would like to retrieve this value using the resultset below. (I have tried this with mysql and it worked successfully, but I had to switch over to Oracle and now I get a string representation of the ID and not the actually sequence number)
Statement stmt = conn.createStatement();
stmt.executeUpdate(insertCmd, Statement.RETURN_GENERATED_KEYS);
stmt.RETURN_GENERATED_KEYS;
ResultSet rs = stmt.getGeneratedKeys();
if(rs.next()){
log.info("Successful insert");
id = rs.getString(1);
}
The above snippet would return the column int value stored in a mysql table. But since I have switched over to Oracle, the value returned is now a strange string value.
What you're trying to do is take advantage of the RETURNING clause. Let's setup an example table and sequence:
CREATE TABLE "TEST"
( "ID" NUMBER NOT NULL ENABLE,
"NAME" VARCHAR2(100 CHAR) NOT NULL ENABLE,
CONSTRAINT "PK_TEST" PRIMARY KEY ("ID")
);
CREATE SEQUENCE SEQ_TEST;
Now, your Java code should look like this:
String insertSql = "BEGIN INSERT INTO TEST (ID, NAME) VALUES (SEQ_TEST.NEXTVAL(), ?) RETURNING ID INTO ?; END;";
java.sql.CallableStatement stmt = conn.prepareCall(insertSql);
stmt.setString(1, "John Smith");
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
stmt.execute();
int id = stmt.getInt(2);
This is not consistent with other databases but, when using Oracle, getGeneratedKeys() returns the ROWID for the inserted row when using Statement.RETURN_GENERATEDKEYS. So you need to use the oracle.sql.ROWID proprietary type to "read" it:
Statement stmt = connection.createStatement();
stmt.executeUpdate(insertCmd, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
oracle.sql.ROWID rid = (oracle.sql.ROWID) rs.getObject(1);
But this won't give you the generated ID of the PK. When working with Oracle, you should either use the method executeUpdate(String sql, int[] columnIndexes) or executeUpdate(String sql, String[] columnNames) instead of executeUpdate(String sql, int autoGeneratedKeys) to get the generated sequence value. Something like this (adapt the value to match the index or the name of your primary key column):
stmt.executeUpdate(INSERT_SQL, new int[] {1});
ResultSet rs = stmt.getGeneratedKeys();
Or
stmt.executeUpdate(INSERT_SQL, new String[] {"ID"});
ResultSet rs = stmt.getGeneratedKeys();
While digging a bit more on this, it appears that this approach is shown in the Spring documentation (as mentioned here) so, well, I guess it can't be totally wrong. But, unfortunately, it is not really portable and it may not work on other platforms.
You should use ResultSet#getLong() instead. If in vain, try ResultSet#getRowId() and eventually cast it to oracle.sql.ROWID. If the returned hex string is actually the ID in hexadecimal flavor, then you can try converting it to decimal by Long#valueOf() or Integer#valueOf().
Long id = Long.valueOf(hexId, 16);
That said, Oracle's JDBC driver didn't support ResultSet#getGeneratedKeys() for a long time and is still somewhat troublesome with it. If you can't get that right, then you need to execute a SELECT CURRVAL(sequencename) on the same statement as you did the insert, or a new statement inside the same transaction, if it was a PreparedStatement. Basic example:
public void create(User user) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
Statement statement = null;
ResultSet generatedKeys = null;
try {
connection = daoFactory.getConnection();
preparedStatement = connection.prepareStatement(SQL_INSERT);
preparedStatement.setValue(1, user.getName());
// Set more values here.
int affectedRows = preparedStatement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
statement = connection.createStatement();
generatedKeys = statement.executeQuery(SQL_CURRVAL);
if (generatedKeys.next()) {
user.setId(generatedKeys.getLong(1));
} else {
throw new SQLException("Creating user failed, no generated key obtained.");
}
} finally {
close(generatedKeys);
close(statement);
close(preparedStatement);
close(connection);
}
}
Oh, from your code example, the following line
stmt.RETURN_GENERATED_KEYS;
is entirely superfluous. Remove it.
You can find here another example which I posted before about getting the generated keys, it uses the normal getGeneratedKeys() approach.

Categories

Resources