Query and Update - java

I am trying to query a database records and update at the same time.
the field UserSerial in database needs to be increased by 1 to create a kind of internal serial number, I am using a variable name counter to do that.
When I run the code, I see that the highest counted number (number of records in database) is stored in the UserSerial.
Can someone have a look at my code and tell me what my mistake is?
public class UsersMenu_Fill_usersSerialNumber {
PreparedStatement statement;
PreparedStatement statementUPD;
private Connection con = null;
private Connection conUPD = null;
private String sql_qry;
private String sql_upd;
int counter = 0;
public void UsersMenu_Fill_usersSerialNumber(){
DBModule.ConnectDataBase.ConnectDataBase_Method();
con = DBModule.ConnectDataBase.ConnectDataBase_Method();
conUPD = DBModule.ConnectDataBase.ConnectDataBase_Method();
sql_qry = "select UserSerial from users";
sql_upd = "update users set UserSerial = ?";
try {
statement = con.prepareStatement(sql_qry);
statementUPD = conUPD.prepareStatement(sql_upd);
ResultSet rslt = statement.executeQuery();
while (rslt.next()){
String FieldToChange = rslt.getString("UserSerial");
int FieldToChange_int = Integer.parseInt(FieldToChange);
counter++;
FieldToChange_int = counter;
statementUPD.setString(1, String.valueOf(FieldToChange_int));
statementUPD.executeUpdate();
}
statement.close();
} catch (SQLException ex) {
Logger.getLogger(UsersMenu_Fill_usersSerialNumber.class.getName ()).log(Level.SEVERE, null, ex);
}
}
}

So, there's a couple of things you need to know/do. Firstly, you need to pull back a unique identifier for your row, and use that identifier in your update sql to indicate which row should be updated. I'm going to assume that you've got an ID column on your users table, and use that.
Secondly, you need to retrieve that ID in your select statement, rather then the userSerial which you don't actually need to retrieve.
Then as you loop through, you need to uniquely update the value based on a where clause in the update statement that you specify with your unique id, ID.
I updated your function only to make demonstrate. I did not test this at all, it's just a guide to get you moving.
public void UsersMenu_Fill_usersSerialNumber(){
DBModule.ConnectDataBase.ConnectDataBase_Method();
con = DBModule.ConnectDataBase.ConnectDataBase_Method();
conUPD = DBModule.ConnectDataBase.ConnectDataBase_Method();
sql_qry = "select ID from users";
sql_upd = "update users set UserSerial = ? where ID = ?";
try {
statement = con.prepareStatement(sql_qry);
statementUPD = conUPD.prepareStatement(sql_upd);
ResultSet rslt = statement.executeQuery();
while (rslt.next()){
Long id = statement.getLong("ID");
counter++;
statementUPD.setString(1, String.valueOf(counter));
statementUPD.setLong(2, String.valueOf(id));
statementUPD.executeUpdate();
}
statement.close();
} catch (SQLException ex) {
Logger.getLogger(UsersMenu_Fill_usersSerialNumber.class.getName ()).log(Level.SEVERE, null, ex);
}
}

Related

how to know when a select finds 0 rows mysql, getFetchSize() not working

I am trying to make a username only register if that name is not taken, using JDBC connection and checking on SQL Database.
I have the code that checks for the
SELECT * FROM user
WHERE username = 'jessica';
and it finds 2 rows;
Searched a lot and found that with getFetchSize() it would give me the number of rows, and if it finds null it would return 0.
It is always returning 0, I don't know why, because I have the usernames taken twice, it lets me add me always...
https://prnt.sc/galyqo
public int nameAvailable(MyUserApp app, String name) throws SQLException{
String sql = "SELECT * FROM user \n WHERE username = '"+ name +"';";
Statement st = app.getCon().createStatement();
ResultSet rs = st.executeQuery(sql);
int numResults = rs.getFetchSize();
return numResults;
}
This is the register code:
private void RegisterButtonActionPerformed(java.awt.event.ActionEvent evt) {
String username, password, address, dob;
boolean status;
String u;
try {
username = newUsernameField.getText();
password = passwordField2.getText();
address = addressField.getText();
dob = dateofbField.getText();
int no= 5;
if( username.isEmpty() || password.isEmpty() || password.length() < 6 ){
jLabel6.setText("The information you typed in is not valid. ");
status = false;
showTableDB.setText(""+status);
}
else{
no = this.app.nameAvailable(app, username);
jLabel6.setText(no+"");
if(no == 0){
jLabel6.setText("Registered your account, "+username+"!" + no);
status = this.app.registerUser(app, username, password, dob, address);
u = this.app.showInfo(app, username);
showTableDB.setText(u);
no = this.app.nameAvailable(app, username);
}
else{
showTableDB.setText("That username is token. Please choose a different one.");
}
}
} catch (SQLException ex) {
Logger.getLogger(UserAppUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(UserAppUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
Resolved. Solution:
public int getNCount(MyUserApp app, String name) throws SQLException{
String sql = "SELECT COUNT(*) FROM user \n WHERE username = '"+ name +"';";
int rowCount;
PreparedStatement st = app.getCon().prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet r = st.executeQuery(sql);
r.next();
// get the number of rows from the result set. On the db it will show a table with "count(*)" and the #counts
rowCount = r.getInt("count(*)");
r.close();
st.close();
return rowCount;
}
By calling these statement on the code:
r.next()
and then
rowCount = r.getInt("count(*)");
I was able to get the 2nd column of the count(*) SQL Statement.
The fetch size is not the same thing as the number of rows. The fetch size is just a way of limiting how many rows at a time will be fetched from the database.
There's no easy way to check the number of rows returned by a select statement. If you really need to know how many rows there are, in the case there's more than one, then one approach would be to iterate through the result set, copying the information that you need from each row into memory; then check the amount of data that you copied at the end.
Alternatively, if you don't actually need any data from the rows themselves, you could try a statement like SELECT count(*) FROM user WHERE username = ?.
One more thing - you need to read about SQL injection attacks. This is where a hacker uses your code to run SQL that they shouldn't. The code you've shown here is vulnerable to an SQL injection attack. But that's another question entirely.
Resolved. Solution:
public int getNCount(MyUserApp app, String name) throws SQLException{
String sql = "SELECT COUNT(*) FROM user \n WHERE username = '"+ name +"';";
int rowCount;
PreparedStatement st = app.getCon().prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet r = st.executeQuery(sql);
r.next();
// get the number of rows from the result set. On the db it will show a table with "count(*)" and the #counts
rowCount = r.getInt("count(*)");
r.close();
st.close();
return rowCount;
}
By calling these statement on the code:
r.next()
and then
rowCount = r.getInt("count(*)");
I was able to get the 2nd column of the count(*) SQL Statement.

Retrieving data from database and increment by one

I am trying to retrieve a data (ID No.) from a database (MySQL) and add it by one. However, when I try to put this code below, when I try to build it, the form doesn't show up. But when I try to remove the Connection cn line, the form with finally show up. I had another project with this code it it worked perfectly fine. I'm not sure why its not working on this one.
public Abstract() throws Exception {
Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user?zeroDateTimeBehavior=convertToNull","root","");
initComponents();
Statement st = null;
ResultSet rs;
try {
String sql = "SELECT ID from bidding_abstractofprices";
st = cn.prepareStatement(sql);
rs = st.executeQuery(sql);
while(rs.next()){
int id = Integer.parseInt(rs.getString("ID")) + 1;
lblTransacID.setText(String.valueOf(id));
}
}catch (Exception ex){
}
}
What it looks like you are trying to do is to get the ID field value from the last record contained within the bidding_abstractofprices Table contained within your Database and then increment that ID value by one (please correct me if I'm wrong). I don't care why but I can easily assume. Here is how I might do it:
public Abstract() throws Exception {
// Allow all your components to initialize first.
initComponents();
Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user?zeroDateTimeBehavior=convertToNull","root","");
Statement st = null;
ResultSet rs;
try {
String sql = "SELECT * FROM bidding_abstractofprices ORDER BY ID DESC LIMIT 1;";
st = cn.prepareStatement(sql);
rs = st.executeQuery(sql);
int id = 0;
while(rs.next()){
id = rs.getInt("ID") + 1;
}
lblTransacID.setText(String.valueOf(id));
rs.close();
st.close();
cn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}

JDBC Discover row based on a value in column

Need help from you all in writing up this query.
I have two columns, X and Y.
I have found a value in column Y and I am trying to find its row number.
Alternatively, I was trying to do:
SELECT ID in COLUMN_NAME from TABLE_NAME WHERE COLUMN_NAME2 contains some value I have already retrieved!
private int findRow(int value) throws SQLException {
Connection mysqlConn = DriverManager.getConnection(DB_URL, USER, PASS);
try {
String query ="SELECT BUILDING FROM ALLBUILDINGS WHERE BUILDINGNUMBER = 'value'";
Statement st = mysqlConn.prepareStatement(query);
ResultSet rs = st.executeQuery(query);
while (rs.next()) {
value = rs.getInt(value);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return value;
}
Can someone tell me how I could do either of the aforementioned?
Thanks in advance!
This should solve your problem.
private int findRow(int value) throws SQLException {
Connection mysqlConn = DriverManager.getConnection(DB_URL, USER, PASS);
try {
String query ="SELECT BUILDING FROM ALLBUILDINGS WHERE BUILDINGNUMBER = ?";
PreparedStatement st = mysqlConn.prepareStatement(query);
st.setInt(1,value);
ResultSet rs = st.executeQuery(query);
while (rs.next()) {
value = rs.getString(1);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return value;
}
I assume you're not trying to find the row index, but instead what the value of the X column is, in the row where Y column = "some_value".
SELECT X FROM ALL_BUILDINGS WHERE Y = "some_value";
This will match all rows where the Y column is "some_value", and return a corresponding set of values from column X.

Resultset error

Im working with Java EE and derby, i try to get data from my resultset and put them in int and string but don't work it gives me this error :
java.sql.SQLException: Invalid operation for the current cursor location.
i tryed result.next() but nothing, here is my code :
Connection conn = null;
Statement stmt = null;
ResultSet result = null;
Hotel hot = new Hotel();
try {
synchronized (dataSource) {
conn = dataSource.getConnection();
}
stmt = conn.createStatement();
String req = "SELECT * FROM hotel WHERE num = " + num;
result = stmt.executeQuery(req);
}
//result.next();
int xxnum = result.getInt(1);
String nom = result.getString("nom");
String villeV = result.getString("ville");
int etoilesV = result.getInt("etoiles");
String directeur = result.getString("directeur");
Hotel hol = new Hotel(num, nom, villeV, etoilesV, directeur);
result.close();
stmt.close();
return hol;
} catch (SQLException ex) {
throw new DAOException("probl�me r�cup�ration de la liste des hotels !!", ex);
} finally {
closeConnection(conn);
}
The error
java.sql.SQLException: Invalid operation for the current cursor location.
will be caused by not setting the cursor to the next position using
result.next();
Place the call in an if statement
if (result.next()) {
// build Hotel object
...
}
If you still don't see any results, run your SQL directly against your database and see if any records are returned. If not, adjust your query or data accordingly.
Side Notes:
Use PreparedStatement to protect against SQL Injection attacks.
Place result.close(); and stmt.close(); calls in a finally block.
You need to use next() method of ResultSet.
Check the Javadocs here and I have snipped the relevant part below.
Moves the cursor froward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.
So you need to do this in your code:
if(result.next())
{
int xxnum = result.getInt(1);
String nom = result.getString("nom");
String villeV = result.getString("ville");
int etoilesV = result.getInt("etoiles");
String directeur = result.getString("directeur");
}

How to create Java method to count rows in Oracle table

I want to create Java method which can count the rows in Oracle table. So far I made this:
public int CheckDataDB(String DBtablename, String DBArgument) throws SQLException {
System.out.println("SessionHandle CheckUserDB:"+DBArgument);
int count;
String SQLStatement = null;
if (ds == null) {
throw new SQLException();
}
Connection conn = ds.getConnection();
if (conn == null) {
throw new SQLException();
}
PreparedStatement ps = null;
try {
conn.setAutoCommit(false);
boolean committed = false;
try {
SQLStatement = "SELECT count(*) FROM ? WHERE USERSTATUS = ?";
ps = conn.prepareStatement(SQLStatement);
ps.setString(1, DBtablename);
ps.setString(2, DBArgument);
ResultSet result = ps.executeQuery();
if (result.next()) {
count = result.getString("Passwd");
}
conn.commit();
committed = true;
} finally {
if (!committed) {
conn.rollback();
}
}
} finally {
/* Release the resources */
ps.close();
conn.close();
}
return count;
}
I want to use for different tables. This is the problem that I cannot solve:
count = result.getString("row");
Can you help me to solve the problem?
count = result.getInt(1);
This is needed, because count is int. And you can specify the index of the row returned by the query, you don't need to access it by name.
But you could also do:
count = result.getInt("count(*)");
This should do it:
count = result.getInt("count(*)");
You need to use the same name as you specified in your query to get the value. You could also make your
count = result.getString("row");
work by changing your query to
SQLStatement = "SELECT count(*) as row FROM ? WHERE USERSTATUS = ?";
You cannot use bind variable in place of a database object in an SQL query, can you? It can only be used for parameter binding.
Try this instead,
"SELECT count(*) as row_count FROM " + DBtablename + " WHERE USERSTATUS = ?";
This could be vulnerable to SQL Injection so you might want to check that DBtablename parameter is a valid database object name (i.e. at most 30 bytes long without spaces, and contains only valid chars for database object identifiers).
count = result.getInt("row_count");

Categories