Can not get inserted primary key at JDBC - java

I am working with Microsoft SQL Server in my project and I am using JDBC as connector. My project runs within Tomcat Server. What I am trying to do is gettiing primary key of a newly inserted value without writing one more select statement.
Here is my java code:
PreparedStatement ps = conn.prepareStatement("INSERT INTO Users(FIRSTNAME,STATUS)VALUES " +
"(?,?)", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, "name");
ps.setInt(2, status);
int updatedRows = ps.executeUpdate();
if(updatedRows > 0){
ResultSet resultSet = ps.getGeneratedKeys();
if (resultSet.next()) {
// do some stuff with resultSet.getInt(1)
// but code does not enter here
}
}
But code does not enter the inner if clause statement as I mentioned in my comment. I also tried this:
PreparedStatement ps = conn.prepareStatement("INSERT INTO Users(FIRSTNAME,STATUS)VALUES " +
"(?,?)", new String[]{"USERID"});
Here USERID is name of the primary key of Users table. Both method did not worked. How can I solve this?

try this:
INSERT INTO Users(FIRSTNAME,STATUS) OUTPUT Inserted.ID VALUES (?,?)

Related

inserting new user object into JDBC through the servlet

Here is the code for my servlet which recieves username parameter from a registration form
String tusername=request.getParamater("un");
String dbURL="db.com";
String dbusername= "lc";
String dbpassword="lcpw";
Connection con=(Connection) DriverManager.getConnection(dbURL,dbusername,dbpassword);
Statement stmt= con.createStatement();
String query="SELECT * FROM users.username WHERE username=(tusername)";
ResultSet rs= stmt.executeQuery(query);
if(rs.next()==false){
//create new userobject with value of tusername
}
My question is how do I create a new user object with calue of tusername, would it be like so ?
if(rs.next()==false){
Statement stmt=con.createStatament();
String query="INSERT INTO user.username VALUE 'tusername'";
ResultSet rs= stmt.updateQuery(query);
}
I understand some of this might be archaic (such as not using a prepared statement) , I am just trying to better my understanding and I think I am having some small syntax issues, thanks :)
You should be using a NOT EXISTS query to do the insert, and also you should ideally be using a prepared statement:
String sql = "INSERT INTO user.username (username) ";
sql += "SELECT ? FROM dual WHERE NOT EXISTS (SELECT 1 FROM user.username WHERE username = ?)";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, tusername);
ps.setString(2, tusername);
int result = ps.executeUpdate();
if (result > 0) {
System.out.println("Inserted new user " + tusername + " into username table";
}
else {
System.out.println("User " + tusername + " already exists; no new record was inserted");
}
I don't know what your actual database is. The above should work out of the box for MySQL and Oracle. It might need to be modified slightly for other databases.
An alternative to the above query would be to just use your current insert, but make the username column a (unique) primary key. In that case, any attempt to insert a duplicate would fail at the database level, probably resulting in an exception in your Java code. This would also be a more database agnostic approach.

GetgeneratedKeys not working although row inserted

I use HSQLDB - Tried version 2.3.4 and 2.4.
I have this Java code:
String sqlquery = "MERGE INTO bewertung pu USING "
.concat("(VALUES ?,?,?) ")
.concat("temp (tid,jurorid,runde) ")
.concat("ON temp.tid = pu.tid and temp.jurorid=pu.jurorid and temp.runde=pu.runde ")
.concat("WHEN NOT MATCHED THEN ")
.concat("INSERT (tid,jurorid,runde) ")
.concat("VALUES (temp.tid,temp.jurorid,temp.runde)");
PreparedStatement preparedStatement = sql.getConnection().prepareStatement(sqlquery,
Statement.RETURN_GENERATED_KEYS);
preparedStatement.setInt(1, eineBewertung.getTanzID()); //TID
preparedStatement.setInt(2, eineBewertung.getJurorID()); //JURORID
preparedStatement.setInt(3, eineBewertung.getRunde()); //RUNDE
int rowsAffected = preparedStatement.executeUpdate();
if (rowsAffected == 0) {
//UPDATE
//DO SOMETHING
}else{
//INSERT
try (ResultSet rs = preparedStatement.getGeneratedKeys()) {
if (rs.next()) {
eineBewertung.setBewertungsid(rs.getInt(1));
}
}catch (SQLException ex) {
this.controller.error_ausgeben(ex);
}
}
It works. If I insert a new row I get rowsAffected = 1. I check the database and the insert worked.
But, I do not get anything back in the resultset getGeneratedKeys()
It is every time empty.
I have found some tips to replace Statement.RETURN_GENERATED_KEYS with the primary key. But this didn`t work for me.
PreparedStatement preparedStatement = sql.getConnection().prepareStatement(sqlquery,
new String[]{"BEWERTUNGSID"});
This is how I create the table:
statement.execute("create table PUBLIC.BEWERTUNG"
.concat("(BEWERTUNGSID INTEGER IDENTITY,")
.concat("TID INTEGER FOREIGN KEY REFERENCES Tanz(Tanzid),")
.concat("JURORID INTEGER not null FOREIGN KEY References JUROR(JURORID),")
.concat("RUNDE INTEGER not null,")
.concat("primary key(BEWERTUNGSID)")
.concat(")"));
Why do I not get any generated keys back? Thank you
//EDIT
If I replace my sqlquery with an insert statement it is working.
sqlquery = "INSERT INTO BEWERTUNG(TID, JURORID, RUNDE) VALUES(22, 2, 2)";
Why is merge not working in the sqlquery?
With versions of HSQLDB up to 2.4.0, generated keys are not available when inserting data using a MERGE statement. Code has been committed to allow this in the next version.

postgresql insertion through java

I've encountered a strange problem. I've got a table, where I want insert data to from java servlet.
The table consits of 3 fields - id - serial (auto inc), name - text, path - text.
So, when I try to insert data with this code:
PreparedStatement statement = null;
ResultSet rs = null;
statement = context.getDBConnection().prepareStatement("INSERT INTO systems (name, path) VALUES ('" + request.getParameter("system_name") + "','" + request.getParameter("system_path") + "')");
rs = statement.executeQuery();
rs.close();
Nothing happens then. Respone from postresql is "No results were returned by the query" BUT when I insert rows manualy through pgAdmin, their id evaulated like the rows were inserted. For example, I've manualy inserted row, so it got id = 1. Then, after a couple of tries to insert data through servlet, I try to insert data manualy again, and row id is 4, not 2.
UPDATE
Modified code, now getting no error, but nothing happens.
PreparedStatement statement = null;
// ResultSet rs = null;
statement = context.getDBConnection().prepareStatement("INSERT INTO systems (system_name, folder_path) VALUES (?,?)");
statement.setString(1, request.getParameter("system_name"));
statement.setString(2, request.getParameter("system_path"));
int i = statement.executeUpdate();

How to get the Generated insert ID in JDBC?

My source code has the following structure:
SourceFolder
AddProduct.jsp
Source Packages
-Controller(Servlets)
SaveProduct.java
-Model(Db Operations)
ProductDbOperations.java
I am inserting a new product into the product table and at the same time I am inserting an entry into product_collection table (product_id | collection_id).
To insert an entry into the product_collection table i need to get generated id from product table. After that a new entry is inserted into the product_collection table.
Also, I am not using any Framework and am using Netbeans 7.3.
Problem:
A new entry is inserted into the product table with this piece of code
IN: ProductDbOperations.java
try
{
this.initConnection(); // Db connection
pst = cn.prepareStatement("INSERT INTO product values('"+name+"', "+quantity+", "+price+")");
rs = pst.executeUpdate();
}
catch(SQLException ex)
{
}
I Also used the solution at following link which doesn't works for me.
I didn't got any SQL exception
How to get the insert ID in JDBC?
so help me find out why this code not working for me .
Thanks a million.
Not all drivers support the version of getGeneratedKeys() as shown in the linked answer. But when preparing the statement, you can also pass the list of columns that should be returned instead of the "flag" Statement.RETURN_GENERATED_KEYS (and passing the column names works more reliably in my experience)
Additionally: as javaBeginner pointed out correctly, your usage of a prepared statement is wrong. The way you do it, will still leave you wide open to SQL injection.
// run the INSERT
String sql = "INSERT INTO product values(?,?,?)";
pst = cn.prepareStatement(sql, new String[] {"PRODUCT_ID"} );
pst.setString(1, name);
pst.setInt(2, quantity);
pst.setInt(3, price);
pst.executeUpdate();
// now get the ID:
ResultSet rs = pst.getGeneratedKeys();
if (rs.next()) {
long productId = rs.getLong(1);
}
Note that the column name passed to the call is case-sensitive. For Oracle the column names are usually uppercase. If you are using e.g. Postgres you would most probably need to pass new String[] {"product_id"}
The way you are using is not the proper way of using preparedstatement
use the following way
pst = cn.prepareStatement("INSERT INTO product values(?,?,?)");
pst.setString(1,name);
pst.setInt(2,quantity);
pst.setInt(3,price);
pst.executeUpdate();
Yes there is a way to retrieve the key inserted by SQL. You can do it by:
Using Statement.RETURN_GENERATED_KEYS in your previous insert and get the key which can be used in further insert
e.g:
String query = "INSERT INTO Table (Col2, Col3) VALUES ('S', 50)";
Statement stmt = con.createStatement();
int count = stmt.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);

Using Oracle sequence to insert log id into 2 tables from jdbc?

I am using oracle sequence for inserting log id into tableA as follows,
String SQL_PREP_INSERT = "INSERT INTO tableA (LOG_ID,USER_ID,EXEC_TIME) VALUES"
+ " (logid_seq.nextval, ?, ?)";
Then getting the recently inserted value,
String SQL_PREP_SEL = "SELECT max(LOG_ID) FROM tableA ";
stmt = con.prepareStatement(SQL_PREP_SEL);
stmt.execute();
ResultSet rs = stmt.getResultSet();
if (rs.next()) {
logid = rs.getInt(1);
}
And inserting it into tableB,
String SQL_PREP_INSERT_DETAIL = "INSERT INTO tableB (LOG_ID, RESPONSE_CODE, RESPONSE_MSG) VALUES"
+ " (?, ?)";
stmt = con.prepareStatement(SQL_PREP_INSERT_DETAIL);
stmt.setInt(1, logid);
stmt.setString(2, respCode);
stmt.setString(3, respMsg);
stmt.execute();
Is there a way to generate sequence in Java instead of Oracle and insert into both tables at once, instead of selecting from tableA and inserting into tableB?
In general, selecting the MAX(log_id) is not going to give you the same value that logid_seq.nextval provided. Assuming that this is a multi-user system, some other user could have inserted another row with a larger log_id value than the row you just inserted before your query is executed.
Assuming that both INSERT statements are run in the same session, the simplest option is probably to use the logid_seq.currval in the second INSERT statement. currval will return the last value of the sequence that was returned to the current session so it will always return the same value that was generated by the nextval call in the first statement.
INSERT INTO tableB (LOG_ID, RESPONSE_CODE, RESPONSE_MSG)
VALUES( logid_seq.currval, ?, ? )
Alternatively, you could use the RETURNING clause in your first statement to fetch the sequence value into a local variable and use that in the second INSERT statement. But that is probably more work than simply using the currval.
String QUERY = "INSERT INTO students "+
" VALUES (student_seq.NEXTVAL,"+
" 'Harry', 'harry#hogwarts.edu', '31-July-1980')";
// load oracle driver
Class.forName("oracle.jdbc.driver.OracleDriver");
// get database connection from connection string
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:sample", "scott", "tiger");
// prepare statement to execute insert query
// note the 2nd argument passed to prepareStatement() method
// pass name of primary key column, in this case student_id is
// generated from sequence
PreparedStatement ps = connection.prepareStatement(QUERY,
new String[] { "student_id" });
// local variable to hold auto generated student id
Long studentId = null;
// execute the insert statement, if success get the primary key value
if (ps.executeUpdate() > 0) {
// getGeneratedKeys() returns result set of keys that were auto
// generated
// in our case student_id column
ResultSet generatedKeys = ps.getGeneratedKeys();
// if resultset has data, get the primary key value
// of last inserted record
if (null != generatedKeys && generatedKeys.next()) {
// voila! we got student id which was generated from sequence
studentId = generatedKeys.getLong(1);
}
}

Categories