Retrieving data from database and increment by one - java

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();
}
}

Related

Return a dynamic array based on SQL

I would like to create a method that returns an array with all the values from the database.
This is what I have so far:
package ch.test.zt;
import java.sql.*;
class Database {
static boolean getData(String sql) {
// Ensure we have mariadb Driver in classpath
try {
Class.forName("org.mariadb.jdbc.Driver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url = "jdbc:mariadb://localhost:3306/zt_productions?user=root&password=test";
try {
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
return rs.next();
}
catch (SQLException e) {
e.printStackTrace();
}
return false;
}
}
That means, I could use Database.getData("SELECT * FROM users") and I get an array with all the data from the database that I need.
In my code above I am using return rs.next();, which is definitely wrong. That returns true.
rs.next(); just tell whether your result set has data in it or not i.e true or false , in order to use or create array of the actual data , you have to iterate over your result set and create a user object from it and have to add that object in your users list
Also change the signature
static List<User> getData(String sql)
And best to use like Select Username,UserId from Users; as your sql
something like this:
try { List<User> userList = new ArrayLisy();
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
//until there are results in the resultset loop over it
while (rs.next()) {
User user = new User();
user.SetName(rs.getString("username"));
// so on.. for other fields like userID ,age , gender ,loginDate,isActive etc ..
userList.add(user);
}
}
when you don't know about the columns of the table you are going to fetch then you can find the same using :
Now you know all the information then you can construct a proper query using it
and work from this
DatabaseMetaData metadata = connection.getMetaData();
ResultSet resultSet = metadata.getColumns(null, null, "users", null);
while (resultSet.next()) {
String name = resultSet.getString("COLUMN_NAME");
String type = resultSet.getString("TYPE_NAME");
int size = resultSet.getInt("COLUMN_SIZE");
System.out.println("Column name: [" + name + "]; type: [" + type + "]; size: [" + size + "]");
}
}

Unable to execute prepared Statement from DAO

So currently Im trying to do get the auto-incremented primary key by following this answer
Primary key from inserted row jdbc? but apparently the program can't even reach that line and the error appeared on the ps.executeQuery() line after debugging the program, the error it display was only "executeQuery" is not a known variable in the current context. that line, which didn't make sense to me. So how do I go pass this hurdle?
public static int createNewLoginUsers(String newPassword, String newRole) throws SQLException{
Connection conn = DBConnection.getConnection();
Statement st = null;
ResultSet rs = null;
PreparedStatement ps = null;
int id = 0;
try{
String sql = "INSERT into Login(password, role) VALUES(?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, newPassword);
ps.setString(2, newRole);
ps.executeUpdate();
st = conn.createStatement();
rs = st.executeQuery("SELECT * from Login");
rs.last();
System.out.println(rs.getInt("username"));
id = rs.getInt("username");
rs.close();
} finally{
try{
conn.close();
}catch(SQLException e){
System.out.println(e);
}
}
return id;
}
The part of the method which calls the createNewLoginUsers method
if(newPasstxtfld.getText().equals(retypeNewPasstxtfld.getText())){
//update into database
try {
int username = CreateUsersDAO.createNewLoginUsers( (String) newUserRoleBox.getSelectionModel().getSelectedItem(), newPasstxtfld.getText());
Alert confirmation = new Alert(Alert.AlertType.INFORMATION);
confirmation.setHeaderText("New User Details has been created. Your username is " + username);
confirmation.showAndWait();
} catch (SQLException e) {
}
EDIT:
Databases table added and it's in the provided link below
https://imgur.com/a/Dggp2kc and edit to the codes instead of 2 try blocks in one method i have placed it into a different similar method, updated my codes to the current one I have.

Query and Update

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);
}
}

Java JDBC Incorrect Syntax Error

I have this method to load the objects, however when I am running the sql code it is giving me a Syntax error.
public void loadObjects() {
Statement s = setConnection();
// Add Administrators
try {
ResultSet r = s.executeQuery("SELECT * FROM Administrator;");
while (r.next()) {
Administrator getUser = new Administrator();
getUser.ID = r.getString(2);
ResultSet r2 = s.executeQuery("SELECT * FROM Userx WHERE ID= {" + getUser.ID + "};");
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
I have tried inserting the curly braces as stated in other questions, but I am either doing it wrong or it doesn't work.
This method should be able to load all administrators but I believe it is only inserting half of the ID.
The ID that it gets, consists of numbers and char; example "26315G"
the Error -
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '26315'.
Edit -
private java.sql.Connection setConnection(){
java.sql.Connection con = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url = "jdbc:sqlserver://" + host + ";DatabaseName=" + database + ";integratedSecurity=true;";
con = DriverManager.getConnection(url, username, password);
} catch(Exception e) {
System.out.println(e);
}
return con;
}
public void loadObjects() {
java.sql.Connection con = setConnection();
// Add Administrators
try {
PreparedStatement sql = con.prepareStatement("SELECT * FROM Administrator");
ResultSet rs = sql.executeQuery();
while (rs.next()) {
Administrator getUser = new Administrator();
getUser.ID = rs.getString(2);
PreparedStatement sql2 = con.prepareStatement("SELECT * FROM Userx WHERE ID=?");
sql2.setString(1, getUser.ID);
ResultSet r2 = sql2.executeQuery();
getUser.name = r2.getString(2);
getUser.surname = r2.getString(3);
getUser.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(getUser);
}
} catch (Exception e) {
System.out.println(e);
}
}
Actually it is not the way to do that in JDBC. That way, even if you sort your syntax error, your code is prone to sql injection attacks.
The right way would be:
// Let's say your user id is an integer
PreparedStatement stmt = connection.prepareStatement("select * from userx where id=?");
stmt.setInt(1, getUser.ID);
ResultSet rs = stmt.executeQuery();
This way you are guarded against any attempt to inject SQL in your application request parameters
First of all: if you use concurrently result-sets, you must use separate statements for each one of them (you can not share Statement s between two r and r2). And more, you lack r2.next() before reading from it.
On the other hand: it would be much more effective to use PreparedStatement in the loop that to rewrite the query all the time.
So I'd go for something like this:
public void loadObjects() {
try (
Statement st = getConnection().createStatement();
//- As you read (later) only id, then why to use '*' in this query? It only takes up resources.
ResultSet rs = st.executeQuery("SELECT id FROM Administrator");
PreparedStatement ps = getConnection().prepareStatement("SELECT * FROM Userx WHERE ID = ?");
ResultSet r2 = null;
) {
while (rs.next()) {
Administrator user = new Administrator();
user.ID = rs.getString("id");
ps.setInt(1, user.ID);
r2 = ps.executeQuery();
if (r2.next()) {
user.name = r2.getString(2);
user.surname = r2.getString(3);
user.PIN = r2.getLong(4);
JBDeveloping.users.administrators.add(user);
}
else {
System.out.println("User with ID=" + user.ID + " was not found.");
}
}
}
catch (Exception x) {
x.printStacktrace();
}
}
Please note use of Java7 auto-close feature (you didn't close resources in you code). And last note: until you are not separating statements in your queries, as to JDBC documentation, you should not place ';' at the end of statements (in all cases you shouldn't place ';' as the last character in you query string).
You should not use {} and you should not append parameters into a SQL query like this.
Remove the curly braces and use PreparedStatement instead.
see http://www.unixwiz.net/techtips/sql-injection.html

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");
}

Categories