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 (?,?)
I have this method in my DAO class to insert record to a table called idea this is my method:
public long addIdea(AddIdeaDto addIdeaDto, int userId) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = getConnection();
preparedStatement = connection.prepareStatement(
"INSERT INTO IDEA ( IDEA.I_ID,IDEA.I_NO,IDEA.I_APPROVER_NAME_CODE, IDEA.I_TITLE,IDEA.I_DESCRIPITION, IDEA.I_CREATED_DATE,IDEA.I_STATUS_CODE, "
+ "IDEA.I_IS_CODE, IDEA.I_CONTRIBUTION_CODE, IDEA.I_POSITIVE_IMPACT, IDEA.I_SECOND_MEMBER_ID,IDEA.I_THIRD_MEMBER_ID,IDEA.I_FOURTH_MEMBER_ID,"
+ "IDEA.I_FIFTH_MEMBER_ID, IDEA.I_POINTS,IDEA.I_CREATED_USER_ID)"
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
preparedStatement.executeQuery("SELECT IDEA_SEQ.nextval FROM DUAL");
// Set parameters
preparedStatement.setObject(1, Types.NUMERIC);
preparedStatement.setObject(2, Types.NUMERIC);
preparedStatement.setObject(3, addIdeaDto.getApproverNameCode());
preparedStatement.setString(4, addIdeaDto.getTitle());
preparedStatement.setString(5, addIdeaDto.getDescription());
preparedStatement.setDate(6, addIdeaDto.getCreatedDate() == null ? null
: new java.sql.Date(addIdeaDto.getCreatedDate().getTime()));
preparedStatement.setObject(7, addIdeaDto.getStatusCode());
preparedStatement.setObject(8, addIdeaDto.getIsNewCode());
preparedStatement.setObject(9, addIdeaDto.getContributionCode());
preparedStatement.setString(10, addIdeaDto.getPositiveImpact());
preparedStatement.setObject(11, addIdeaDto.getSecondMemberName());
preparedStatement.setObject(12, addIdeaDto.getThirdMemberName());
preparedStatement.setObject(13, addIdeaDto.getFourthMemberName());
preparedStatement.setObject(14, addIdeaDto.getFifthMemberName());
preparedStatement.setObject(15, addIdeaDto.getPoints());
preparedStatement.setInt(16, userId);
preparedStatement.executeQuery();
return addIdeaDto.getIdeaId();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
actually what I want is after or before the insert statement I want to get the id (IDEA_SEQ.nextval) and save it in a value in order to use it as an input to insert in anther table.
For example, I insert this record : id = 1 , no = 1, approver code = 2, title = 'test'.............
I want this value id = 1 to use it in order to insert in table A, A_id = 33, IDEA.I_ID = 1, A_name ='testing'
how i can achieve it in properer way?
I update the code based on the comments that i receive but I did not achieve it
Usually ID that need to be reuse can be handle using a previous and separate SQL query
previousPreparedStatement = connection.prepareStatement(
"select IDEA_SEQ.nextval as nextval from dual");
Result saved as a int or String parameter according to column (number or varchar) which is passed to the existing insert statement:
(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
Notice also an answer from DBA forum
you won't be able to use plain SQL to overcome this limitation: you will need some PL/SQL
A better way to handle this is the RETURNING INTO clause, which uses a single, atomic statement:
INSERT INTO mytable (id, col1, col2)
VALUES ( seq_id.nextval, c1, c2 )
RETURNING id INTO myval;
You can use PreparedStatement.getGeneratedKeys() to obtain the generated value. There is no need to use a separate statement:
You also can't prefix column names with the table name in list of columns of an INSERT statement.
String insert =
"INSERT INTO IDEA ( I_ID,I_NO,I_APPROVER_NAME_CODE, I_TITLE,I_DESCRIPITION, I_CREATED_DATE,I_STATUS_CODE, "
+ "I_IS_CODE, I_CONTRIBUTION_CODE, I_POSITIVE_IMPACT, I_SECOND_MEMBER_ID,I_THIRD_MEMBER_ID,I_FOURTH_MEMBER_ID,"
+ "I_FIFTH_MEMBER_ID, I_POINTS,I_CREATED_USER_ID)"
+ " VALUES (idea_seq.nextval,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
preparedStatement = connection.prepareStatement(insertSql, new String[] {"I_ID"});
preparedStatement.setInt(1, ???); // don't know where the value for I_NO comes from
preparedStatement.setString(2, addIdeaDto.getApproverNameCode());
preparedStatement.setString(3, addIdeaDto.getTitle());
... other parameters
preparedStatement.executeUpdate();
ResultSet rs = preparedStatement.getGeneratedKeys();
long newId = -1;
if (rs.next()) {
newId = rs.getLong("I_ID");
}
... use the NewId ...
The parameter new String[] {"I_ID"} for the prepareStatement() call tells the JDBC driver to return the generated value for that column. That value can be retrieved through getGeneratedKeys() which returns a ResultSet that contains one row for each inserted row (so exactly one in this case). The ID value can then be extracted from the ResultSet using the the usual getLong() (or getInt()) methods.
I have a ERROR_MSG table which stores error messages with some ids. I want to insert error message if id is not present in table and if its present update error message. Inserting using below java JDBC code.
ID ERROR_MSG
1 ERR1
2 ERR2
3 ERR3
This is my code:
insertQry = "SQL";
Connection con = null;
PreparedStatement stmt = null;
try {
con = getDataSource().getConnection();
stmt = con.prepareStatement(insertQry);
for(ListingAckNackData errorList: listOfListingERROR) {
stmt.setLong(1, eqGlobalData.getSrcMsgId());
stmt.setString(2, errorList.getGliId());
if (null != errorList.getListingRevisionNo()) {
stmt.setInt(3, errorList.getListingRevisionNo());
} else {
stmt.setNull(3, Types.NULL);
}
if (null != errorList.getErrorMessage()) {
stmt.setString(4, errorList.getErrorMessage());
} else {
stmt.setNull(4, Types.NULL);
}
stmt.addBatch();
}
stmt.executeBatch();
}
The simplest solution in JAVA is to check if the row exist.
You start by getting a row count for the specific id you want to insert/update
select count('a') as rowExist from table where id = ?
Then, based on the result, you can easily create your query
if(rowExist > 0){
query = "update ..";
else
query = "insert ...";
Note that the parameters are probably not in the same order as you expect, you need to create the insert in the correct order to have the id at the end (since update need a where clause)
insert into Table (name, birthday, id) values (?, ?, ?)
update Table set name = ?, birthday = ? where id = ?
It is possible to run a database statement as questioned. Simply use SQL command MERGE INTO... IF NOT MATCHED INSERT... IF MATCHED UPDATE ...
You will find an full example and documentation here.
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.
My database contains one column having data type as Integer. I want to delete record using that column value but i'm getting an error.
Here is my code
int id=Integer.parseInt(JOptionPane.showInputDialog(null,"Enter ID to serach"));
//....code
st.executeUpdate("delete from Table where ID='"+id+"'");
I'm getting following error:
Data type mismatch in criteria expression.
you pass a VARCHAR value in your query:
delete from Table where ID='"+id+"'"
just remove the ' and try it again.
I bet your ID is of type NUMBER.
Furthermore I suggest you to use an PreparedStatement to add the Integer value:
delete from Table where ID=?
Otherwise you could have some security problems.
Simple change to :
st.executeUpdate("delete from Table where ID = "+id);
OR
SQLiteDatabase _db = null;
DataBaseHelper _dbHelper = new DataBaseHelper(_context, name, null, 1);
_db = _dbHelper.getWritableDatabase();
_db.delete(TABLE, _ID + "=?", new String[]{id});
So you are inserting integer and not character.Thus no need of single quote around value you are inserting ie int value.It should be
st.executeUpdate("DELETE FROM Table WHERE ID="+id);
It is good practice to have main key words/clauses in Uppercase.And one more, always try to use PreparedStatement rather simple Statement.
EDIT
PreparedStatement Example to insert into database
String insertTableSQL = "INSERT INTO DBUSER"
+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
+ "(?,?,?,?)";
PreparedStatement preparedStatement = dbConnection.prepareStatement(insertTableSQL);
preparedStatement.setInt(1, 11);
preparedStatement.setString(2, "mkyong");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
// execute insert SQL stetement
preparedStatement .executeUpdate();