Max value from auto commit false table - java

My problem is i have set a table auto commit false. I need to get the max id from that table(the currently inserted value of auto increment id). But i am getting the id of the previous committed process. Is it possible to get the value
My real problem is i need to insert into table some values, And need to take the id of the last inserted record from the first table and insert it to the second. The second insertion includes some image upload as well(as part of the code). so it take some delay or can have exceptions. I need to undo all insertions(both in the first and second) by occurring any exceptions. I tried to use commit-roll back method for this. But its not properly working as i mentioned above. main portion of my code is written below
try
{
//getting connection and setting auto commit false
dbHandler dbGetConnect=new dbHandler();
Connection conRegPlot=null;
conRegPlot=dbGetConnect.getconn();
conRegPlot.setAutoCommit(false);
String qryInsertPlot="INSERT INTO property_table(name,message,owner,locality,lattitude,longitude,country,state,city,type,catagory,created,modified,creted_date,zoompoint,mob_no,title,img_path,expire_date,lease_term) VALUES('none','"+description+"','"+sessionUserId+"','"+locality+"','"+lattitude+"','"+longitude+"','"+country+"','"+state+"','"+city+"','"+type+"','"+catagory+"',NOW(),NOW(),CURDATE(),'"+zoom+"','"+mob_no+"','"+title+"','NOT IN USE',"+expireDate+",'"+termsAndConditions+"')";//insertion into the first table
Statement stCrs=conRegPlot.createStatement();
int resp=stCrs.executeUpdate(qryInsertPlot);
String qryGetMaxProperty="SELECT MAX(l_id)"+
" FROM property_table"+
" WHERE stat='active'"+
" AND CURDATE()<=expire_date";
propertyId1=dbInsertPropert.returnSingleValue(qryGetMaxProperty);// get the max id
String qryInsertImage="INSERT INTO image_table(plot_id,ownr_id,created_date,created,modified,stat,img_path) VALUES('"+propertyId1+"','"+sessionUserId+"',CURDATE(),NOW(),NOW(),'active','"+img_pth+"')";
Statement stImg=conRegPlot.createStatement();
stImg.executeUpdate(qryInsertImage);// inserting the image
conRegPlot.commit();
}
catch(Exception exc)
{
conRegPlot.rollback();
}
finally{
conRegPlot.close();
}

Since
And need to take the id of the last inserted record from the first
table and insert it to the second.
You could the use of the new JDBC 3.0 method getGeneratedKeys() for get the generated ID. In ahother hand, you should use PreparedStatement for avoid SQL Injection.
PreparedStatement ps = null;
try {
conn = getConnection();
ps = conn.prepareStatement(myQuery, PreparedStatement.RETURN_GENERATED_KEYS);
ps.setInt(1, anInteger);
...
int rows = ps.executeUpdate();
if (rows == 1) {
ResultSet keysRS = ps.getGeneratedKeys();
if (keysRS.next())
int id = keysRS.getInt(1) // Get generated id
For MySQL, see more in http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-last-insert-id.html#connector-j-examples-autoincrement-getgeneratedkeys

Related

Java SQLite JDBC executeQuery returns empty ResultSet of a non-empty column

My code:
Class.forName("org.sqlite.JDBC");
Connection C = DriverManager.getConnection("jdbc:sqlite:test.db");
Statement S = C.createStatement();
S.execute("CREATE TABLE NUMBER (VALUE INT(1))");
S.close();
S = C.createStatement();
S.execute("UPDATE NUMBER SET VALUE = 0");
S.close();
Statement S = C.createStatement();
ResultSet Value = S.executeQuery("SELECT VALUE FROM NUMBER");
if(Value.next())
{
int Result = Value.getInt("VALUE");
System.out.println("Success");
}
else
{
System.out.println("Failure");
}
S.close();
I would expect the result of this code would be "Success", because it should retrieve the integer value 0 from the column VALUE in the table NUMBER. However, it instead prints "Failure". I cannot figure out if this is because the table is actually empty or because it just can't get the data or what. Any help would be appreciated.
You are executing an UPDATE Statement, but in the order the code is presented, nothing is persisted in Table NUMBER yet, as the UPDATE statement is used to update existing records in a table.
Use an INSERT Statement instead, thus inserting data first, as only this way tuples get created in the table NUMBER. Afterwards, the ResultSet should not be empty anymore.
If you need to learn the concept as such, you could have a look at this W3Schools guide.

How to copy table from one database to another?

I need to take a table from one database and upload it to a different database.
So, I create two separate connection . Here is my code
Connection connection1 = // set up connection to dbms1
Statement statement = connection1.createStatement();
ResultSet result = statement.executeQuery("select * from ............. ");
Connection connection2 = // set up connection to dbms2
// Now I want to upload the ResultSet result into the second database
Statement statement2 = connection2.createStatement("insert into table2 " + result);
statement2.executeUpdate();
The above last lines do not work
How can i do this ? The bottomline is how to reuse a ready resultset
ResultSet is a ready java object . I hope there is a way add it to batch or something like this and executeUpdate , but not to write the result set to some temporary space (List, csv etc.) and the insert
The simplest way to do this is with a prepared statement for the insert. It lets you create a single statement object that can be used to run the query multiple times with different parameter values.
try (final Statement statement1 = connection1.createStatement();
final PreparedStatement insertStatement =
connection2.prepareStatement("insert into table2 values(?, ?)"))
{
try (final ResultSet resultSet =
statement1.executeQuery("select foo, bar from table1"))
{
while (resultSet.next())
{
// Get the values from the table1 record
final String foo = resultSet.getString("foo");
final int bar = resultSet.getInt("bar");
// Insert a row with these values into table2
insertStatement.clearParameters();
insertStatement.setString(1, foo);
insertStatement.setInt(2, bar);
insertStatement.executeUpdate();
}
}
}
The rows are inserted into table2 as you iterate through the results from table1, so there's no need to store the whole result set.
You can also use the prepared statement's addBatch() and executeBatch() methods to queue up all the inserts and send them to the database all at once, instead of sending a separate message to the database for each individual inserted row. But that forces JDBC to hold all the pending inserts in memory locally, which it seems you're trying to avoid. So the one-row-at-a-time inserts are your best bet in this case.
If you don't want to manually list out all the field names for every table in the database, you should be able to do this two-step process instead:
Copy the table schema using the answer in this question.
Use resultSet.getMetaData() to get the list of fields, and use that to drive a modified version of the SELECT/INSERT code in #Wyzard's answer.
I will post code here if I get it working.

What method to create, in order to delete the rows of information from the database?

This is my first time making an application and I am quite new with connecting the netbeans IDE to the MySQL database. I have a delete button in a Jpanel, and I want to be able to delete added rows. At the moment I can delete the added rows but they are of course not delete within the SQL DB which means they will remain there when I restart the application.
This is what I have to delete the rows so far
private void removeProductBtnActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
DefaultTableModel model = (DefaultTableModel) this.productTable.getModel();
int[] rows = productTable.getSelectedRows();
for(int i=0;i<rows.length;i++){
model.removeRow(rows[i]-i);
// If I highlight the rows and delte the, they are still in the SQL database.
//How to remove the complete data from the row in the SQL database? What method to write?
String sql = "DELETE FROM Product WHERE ProductID = ?";
Below I have my query to put it inside the database. (so you know what variables I am using)
public ResultSet insertQuery(String query) {
ResultSet result = null;
try {
Statement statement = connection.createStatement();
statement.executeUpdate(query);
result = statement.getGeneratedKeys();
} catch (SQLException e) {
System.err.println(e);
}
return result;
You have a '?' in your sql but you aren't using prepared statement.
For example's sake try:
String sql = "DELETE FROM Product WHERE ProductID = " + rows[i]-i
Question marks are used for prepared statements in java which (among other things) is used for sanitising inputs. Once you get the rest of your code working you should investigate it.

Need some modification in my code

This is a small part of the application where user can register any number of employees and employee id is generated by using a while loop....As i close the application & start filling the data again in second round...the value of employee id empid resets to zero. Well, as long as the application is running, i get the desired o/p i.e. a unique id is allotted to every employee. I dont want empid's value to start from 0 whenever i start the application. Need alternatives and/or any modification. Code is provided here
int empcount=0;
public void actionPerformed(ActionEvent ae) {
//---------------------If user wants to add data
if(ae.getActionCommand()=="ADD EMPLOYEE") {
System.out.println("ADDING");
try{
empcount=empcount+1;//----------------will assign employees with unique emp id
//--------------------returns the text in name field to variables
String s_name=name.getText();
int s_code=empcount;
String s_dept=dept.getText();
String s_ph=ph.getText();
String s_bg=bg.getText();
String s_add=add.getText();
String s_date=date.getText();
PreparedStatement st=null;
Connection con = null;
Class.forName("org.hsqldb.jdbcDriver");
con = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/", "SA", "");
st=con.prepareStatement("Insert into EmpReg (emp_name,emp_code,emp_ph,emp_bg,emp_add,emp_date,b_id) values(?,?,?,?,?,?,?)");
//---------------------parameters and respective values, passed to the SQL statement
st.setString(1,s_name);
st.setInt(2,s_code);
st.setString(3,s_ph);
st.setString(4,s_bg);
st.setString(5,s_add);
st.setString(6,s_date);
st.setString(7,s_dept);
st.execute();
JOptionPane.showMessageDialog(null,"Data is inserted into the database");
JOptionPane.showMessageDialog(code, "employee code"+ empcount+"");
con.close();
}
catch(Exception Ee){
System.out.println(Ee);
}
}
}
});
The standard SQL way of doing this, is having an "autoincrement" primary key (emp_code), for hsqldb see IDENTITY.
In the SQL INSERT statement leave out the primary key. Now the database generates a unique new key.
After the execution, you can retrieve the generated primary key from the statement with getGeneratedKeys.
This ensures that two parallel processes will not mess up the primary keys.
Why don't you create a field in your DB, that is set to autoIncrementTrue and maybe use it as ID as well. You can also use this field as Employee-Number.
You can check this Link for more Information: http://www.w3schools.com/sql/sql_autoincrement.asp
The generated number will increment every time you insert a new Employee.
You could use a DB like Oracle, MySQL, PostGre and use a Sequence or auto generated ID Column to do that for you

Prepared statement fails, but SQL console works

I am working on a project for uni (happens to be due in 14 hours) and I am at a sticking point. It is a web based web store running in eclipse on apache tomcat and derby.
I have a prepared statement that checks for a user name and passwordhash, no matter what I try this statement returns 0 rows. The same sql runs in the sql scratch pad and returns what is expected.
I have used the debugger to inspect the prepared statement object and the query seems fine. The ?'s in the text are still in place rather than filled with the variables, but that seems normal. I have also tried to run the exact same hand written sql from the console, but without any luck.
The query I run in the sql console is
SELECT * FROM username WHERE username='user#system.com' AND passwordhash='passwordhash'
The prepared statments look like this.
PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
"WHERE emailaddress=?" +
" AND passwordhash=?");
pstmt.setString(1,username);
pstmt.setString(2, username + ":" + passwordLogin);
I am at the point where I have tried everything, and have run out of searches to make. I know this is a uni project and the standard reply is to give people somewhere to look. At this point I need spoon feed a path to go down.
EDIT Here is some more background, I have tried running a known working query in this pipeline and it also fails to return any rows.
public static User getUser(String username, String passwordHash) {
DBBean db = new DBBean();
System.out.println("Logging in for username " + username + " and password " + passwordHash);
try {
ResultSet rs;
PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
"WHERE emailaddress=?" +
" AND passwordhash=?");
pstmt.setString(1,username);
pstmt.setString(2,passwordHash);
//PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.product");
//PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username WHERE emailaddress='user#me.com' AND passwordhash='megahashstring'");
rs = pstmt.executeQuery();
System.out.println("Rows returned\t" + rs.getRow());
if(rs.getRow() < 1)
return null;
int id = rs.getInt("uid");
String name = rs.getString("name");
String emailaddress = rs.getString("emailaddress");
String password = rs.getString("passwordhash");
boolean isAdmin = false;
pstmt = db.prepareStatement("SELECT * FROM reallnice.admin WHERE uid= ?");
pstmt.setInt(1, id);
rs = pstmt.executeQuery();
if(rs.getMetaData().getColumnCount() > 0)
isAdmin = true;
return new User(id,isAdmin,name,emailaddress,password);
} catch(Exception ex) {
System.out.println(ex);
}
return null;
}
I have also included the other queries I have tried for this.
Whenever I see someone having an experience like this: "no matter what I try this statement returns 0 rows," there are two possible reasons that come immediately to mind:
1) You aren't using the database you think you are. Derby's connection URL, if you say ";create=true", will quite happily make a new, empty database when you connect, if it doesn't find an existing database in the location you expect. This sort of problem arises from a confusion over where the databases are created; a database with a relative name will be created in whatever directory turns out to the be derby.system.home of the Derby instance that gets that connection URL. So check to see if you are using a different current working directory, or for some other reason are connecting to a different database than you think you are.
2) You aren't using the schema you think you are. Derby will quite happily create multiple schemas, and each schema has a separate set of tables, so if you are initially connecting as user A, and then later connect as user B, and don't issue SET SCHEMA, then user A and user B have completely separate sets of tables and so you won't be accessing the tables that you think you are. So check to see if you are connecting as the same user and using the same schema when you connect to the database.
Try changing how you display your logging statement
System.out.println("Rows returned\t" + rs.getRow());
getRow() returns the current row number, not how many records were returned. In order to user getRow() to count the number of entries in the result set you would need to move the pointer of the result set to the last entry.
You have also, not called next() yet, which means you aren't pointing at anything (and most likely the reason you always see 0 as the number). Try using
while(rs.next()){ //go through the entire ResultSet}
or
if(rs.next()) { //access the first record in the ResultSet}
So over all, if you change your code to something like the following you may have better results.
rs = pstmt.executeQuery();
if(rs.next()){
System.out.println("Processing Row " + rs.getRow());
//continue on
}else{
System.out.println("No Records");
}
If you have set your table where the username is a unique key, you can be assured this will return 0 or 1 row. Otherwise use the while() option instead of if()
EDIT::
Also as a side note, because you are not calling next()
if(rs.getRow() < 1)
return null;
will always be 0, which returns null from your method.

Categories

Resources