How to make column updatable in JDBC? - java

I'm using JDBC to make a banking system with Java. The user should be able to type in a number in a text field, and deposit said amount of money into the bank account. I would like to then update the account balance in the Microsot Access database.
I currently have this:
try (Connection con = DriverManager.getConnection("jdbc:ucanaccess://C://Users//User//IdeaProjects//Database4.accdb")) {
Statement users = con.createStatement();
ResultSet sr = users.executeQuery("Select * from Registrations");
Boolean duplicate = false;
while (sr.next()) {
if (userID.equals(sr.getString(2))) {
match = sr;
duplicate = true;
System.out.println("Welcome " + match.getString(2));
System.out.println("Your balance is " + match.getString(3));
break;
}
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == depositButton) {
String depositString = depositField.getText();
int depositAmount = Integer.parseInt(depositString);
try {
System.out.println(match.getInt(3) + depositAmount);
match.updateInt("AccBalance", match.getInt(3) + depositAmount);
match.updateRow();
}
catch (SQLException ex) {
ex.printStackTrace();
}
When I try to do this, I get the error 'attempt to assign to non-updatable column'.
I'm very new to Java and tried looking online to find fixes for this issue but couldn't find anything useful.

Try the code below
try (Connection con = DriverManager.getConnection("jdbc:ucanaccess://C://Users//mghosh22//IdeaProjects//Database4.accdb")) {
// Query example UPDATE user SET balance = 10000 WHERE user.id = 1;
PreparedStatement updateBalance = conn.prepareStatement("UPDATE <table> SET balance = ? WHERE <wich row update>");
// For each query parameter, set a value to execute the same
// preparedStatement.setParameterType(countEach?StartingWithOne, yourQueryParameter);
updateBalance.setDouble(1, 10,000.00);
// Execute update return the amount of rows your query affected, how we are talking about account balance, the number of rows affected may be ever one
if (updateBalance.executeUpdate() == 1) {
System.out.println("Row updated");
}
}

Related

SQLException: query does not return results

I am doing a project in Java Swing and using SQLite as my database.
This is the function I wrote for deleting a record from the Room table in my database.
public void Delete() {
String room_code = jTextField5.getText();
String sql = "DELETE FROM Room WHERE room_code = '" + room_code + "'";
try {
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
if (rs.next()) {
JOptionPane.showMessageDialog(null, "Room Deleted Successfully");
}
else {
JOptionPane.showMessageDialog(null, "Invalid Room Code");
}
}
catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
However, I am met with the following Exception: SQLException: query does not return results.
I have tried to use pst.executeUpdate() as suggested in other answers but it says "int cannot be converted into resultset".
A DELETE statement does not return a result set. You should call method executeUpdate rather than method executeQuery.
Also, you can use place holders with a PreparedStatement.
Also you should use try-with-resources
Consider the following code.
public void Delete() {
String room_code = jTextField5.getText();
String sql = "DELETE FROM Room WHERE room_code = ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(room_code);
int count = ps.executeUpdate();
if (count > 0) {
JOptionPane.showMessageDialog(null, "Room Deleted Successfully");
}
else {
JOptionPane.showMessageDialog(null, "Invalid Room Code");
}
}
catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
}

update database based on user input in java

i'm a new programmer, I was given a task to create a class Subject.java, in which it'll ask the students how many subjects they're taking and then store the subjects information into the database, but the problem with my current code is that only one row is updated in the database. My code is as the following, please help me.
System.out.print("\nEnter number of subject: ");
int sub = in.nextInt();
int i=0;
for (i=0; i<sub; i++)
{
System.out.print("\nCode: ");
this.setCode(in.next());
System.out.print("\nName: ");
this.setName(in.next());
System.out.print("\nCredit: ");
this.setCredit(in.nextInt());
// insert into database
ResultSet rs = null;
String sqlInsert = "INSERT INTO subject (code, name, credit) VALUES (?,?,?)";
try (Connection conn = MySQLDB.getConnection();
PreparedStatement pstmt
= conn.prepareStatement(sqlInsert);)
{
// assign parameters for statement
pstmt.setString(1, this.getCode());
pstmt.setString(2, this.getName());
pstmt.setInt (3, this.getCredit());
pstmt.addBatch();
if (pstmt.executeUpdate() == 1)
{
System.out.println("\nNew subject has been created succesfully!");
}
else
{
System.out.println("\nError");
}
}
catch (SQLException ex)
{
System.out.println(ex.getMessage());
}
As Nexevis said , you need to put your Connection code outside your for-loop like below :
// insert into database
ResultSet rs = null;
String sqlInsert = "INSERT INTO subject (code, name, credit) VALUES (?,?,?)";
System.out.print("\nEnter number of subject: ");
int sub = in.nextInt();
int i = 0;
try {
Connection conn = MySQLDB.getConnection();
PreparedStatement pstmt
= conn.prepareStatement(sqlInsert);
for (i = 0; i < sub; i++) {
System.out.print("\nCode: ");
this.setCode( in.next());
System.out.print("\nName: ");
this.setName( in.next());
System.out.print("\nCredit: ");
this.setCredit( in.nextInt());
// assign parameters for statement
pstmt.setString(1, this.getCode());
pstmt.setString(2, this.getName());
pstmt.setInt(3, this.getCredit());
pstmt.addBatch();
}
try {
// execute it to insert the data
pstmt.executeBatch();
} catch (SQLException e) {
System.out.println("Error message: " + e.getMessage());
return; // Exit if there was an error
}
pstmt.close();
conn.close();
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}

Looping try/catch statement

I'm trying to take two random rowid from my database. Everything works but I have a scenario when there is only one rowid. I want to make a loop on my try/catch until there is second number in my database.
What I'm doing wrong? Thank you
public void Kaslaimejo() {
String sql = "SELECT rowid FROM Zaidejai WHERE Pirmas < 4 ORDER BY random() LIMIT 2";
Integer value1 = null, value2 = null;
Integer judesiukas1 = null, judesiukas2 = null;
int a = 0;
int k = 15; // kiek kartu? Reikia infinity padaryti
for (a = 0; a < 3; a++) {
try {
Connection conn = Serveris.connect();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
if (rs.next()) {
value1 = rs.getInt("rowid");
if (rs.next()) {
value2 = rs.getInt("rowid");
PreparedStatement buvo = conn.prepareStatement("UPDATE Zaidejai SET Numeriukas = ? WHERE rowid = ?");
buvo.setInt(1, i);
buvo.setInt(2, value1);
int buvolala = buvo.executeUpdate ();
PreparedStatement buvo2 = conn.prepareStatement("UPDATE Zaidejai SET Numeriukas = ? WHERE rowid = ?");
buvo2.setInt(1, i);
buvo2.setInt(2, value2);
int buvolala2 = buvo2.executeUpdate ();//
i++;
}
System.out.println("Pirmas zaidejas" + value1); // atspausdina 1 random zaideja is duomenu bazes
System.out.println("Antras zaidejas" + value2); // atspausdina 2 random zaideja is duomenu bazes
}
} catch (SQLException e) {
a--;
//System.out.println(e.getMessage());
}
}
}
Right now my program loops two times and then gives me SQLException. How I can loop my program until there is no SQLException?
OK, I've tried to write what I think you're trying to do.
You wait for ever until someone puts at least two entries in the database.
You extract two values, process them, then wait some more.
Some points to watch out:
1. Object comparisons need to be made with .equals() not with ==
2. You might want to provide some way to break out of the infinite loop I've written (while(true)).
3. Careful with null values. They might produce NullPointerException.
4. Try to break up your code into methods. Each large block of code could go into each own method.
public void Kaslaimejo(){
String sql = "SELECT rowid FROM Zaidejai WHERE Pirmas < 4 ORDER BY random() LIMIT 2";
Integer judesiukas1 = null, judesiukas2 = null;
while(true) {
List<Integer> values = new ArrayList<>();
while (values.size() < 2) {
try (Connection conn = Serveris.connect();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
if( rs.next() ){
Integer value = rs.getInt("rowid");
values.add(value);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
try( Connection conn = Serveris.connect()) {
PreparedStatement buvo = conn.prepareStatement("UPDATE Zaidejai SET Numeriukas = ? WHERE rowid = ?");
buvo.setInt(1, i);
buvo.setInt(2, values.get(0));
int buvolala = buvo.executeUpdate ();
PreparedStatement buvo2 = conn.prepareStatement("UPDATE Zaidejai SET Numeriukas = ? WHERE rowid = ?");
buvo2.setInt(1, i);
buvo2.setInt(2, values.get(1));
int buvolala2 = buvo2.executeUpdate ();//
i++;
}catch (SQLException e) {
e.printStackTrace();
}
Connection conn = Serveris.connect();
try {
PreparedStatement pstmt = conn.prepareStatement("SELECT Pirmas FROM Zaidejai WHERE rowid = ?");
PreparedStatement pstmt2 = conn.prepareStatement("SELECT Pirmas FROM Zaidejai WHERE rowid = ?");
pstmt.setInt(1, values.get(0));
pstmt2.setInt(1, values.get(1));
ResultSet myrsv = pstmt.executeQuery();
ResultSet myrsv2 = pstmt2.executeQuery();
{
if (myrsv.next()) {
judesiukas1 = myrsv.getInt("Pirmas");
if (myrsv2.next()) {
judesiukas2 = myrsv2.getInt("Pirmas");
}
}
//System.out.println("Pirmo zaidejo veiksmas" + myrsv.getInt("Pirmas"));
//System.out.println("Antro zaidejo veiksmas" + myrsv2.getInt("Pirmas"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (judesiukas1.equals(judesiukas2)) // careful here. NullPointerException may happen.
{
try {
PreparedStatement laim = conn.prepareStatement("UPDATE Zaidejai SET Rezultatas = ? WHERE rowid = ?"); // ble ble update reikia naudoti , o ne insert into. Insert kai sukuriame nauja kazka tik
PreparedStatement laim2 = conn.prepareStatement("UPDATE Zaidejai SET Rezultatas = ? WHERE rowid = ?");
laim.setString(1, "Lygiosios");
laim.setInt(2, values.get(0));
laim2.setString(1, "Lygiosios");
laim2.setInt(2, values.get(1));
int irasyk = laim.executeUpdate (); // kodel executeupdate, o ne executequery????
int irasyk2 = laim2.executeUpdate (); // kodel executeupdate, o ne executequery????
{
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.print("Lygiosios");
} else {
// (1) - Rock
// (2) Scissors
// (3) - Paper
switch (values.get(0)){
case 1:
if (judesiukas2 == 2)
System.out.print("Zaidejas 1 wins!");
else
System.out.print("Zaidejas 2 wins!");
break;
case 2:
if (judesiukas2 == 3)
System.out.print("Zaidejas 1 wins!");
else
System.out.print("Zaidejas 2 wins!");
break;
case 3:
if (judesiukas2 == 1)
System.out.print("Zaidejas 1 wins!");
else
System.out.print("Zaidejas 2 wins!");
break;
}
}
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The logic becomes easier if you add the values to a list
var values = new ArrayList<Integer>();
while (values.Count < 2) {
try (Connection conn = Serveris.connect();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql))
{
while (values.Count < 2 && rs.next()) {
Integer v = rs.getInt("rowid");
values.Add(v);
}
} catch (SQLException e) {
}
}
//TODO: process the values here
The advantage is, that you can retrieve one value at the first database query and the second at a later one or both in the same round and you don't have to keep track of which one of two variables to use.
(Bear with me with the syntax details, I'm not a Java programmer.)
How i can loop my program until there is no SQLException?
Change this (because, it will only allow to loop two times)
for (a = 0; a < 2; a++) {
to
while(true)
Put everything inside while(true), if exception occurred, then it will come out from the while loop. Something similar :
try
{
while(true)
{
...
...
}
...
}
catch(SQLException e)
{
// do somthing
}

jdbc consume too much memory

I wrote program in that I need to update 10000. The query is:
for (Ticket ticket : existInBoth) {
if (!ticket.isUpdatable() && !ticket.isDeleted()) continue;
String query = String.format("update tickets SET vehicle_id = %d , price = %d , free = %d,time = '%s',date='%s',url='%s',deleted_at=NULL WHERE unique_key = '%s'",
ticket.getVehicle().getId(), ticket.getPrice(), ticket.getFree(), ticket.getTime(), ticket.getDate(), ticket.getUrl(), ticket.getUniqueKey());
if (db.update(query) > 0)
updatedDates.add(ticket.getDate());
}
and db.update
#Override
public int update(String sql) {
synchronized (Main.THREAD_GUARD) {
int result = -1;
Connection connection = open();
try {
Statement statement = connection.createStatement();
result = statement.executeUpdate(sql);
statement.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(connection);
}
return result;
}
}
It seems realy easy. But when I ran it I see this updating take about 300MB of memory.
I carefully close all statements and connections.

Java: Check auto-generated ID

My Java program adds items into database. I have a code for generating random string that will be used as an item ID. I want to make IDchecker(id) that will check whether the ID already exists into database.
If I have codeIDgenerator() and IDchecker(id) methods, how do I make a loop that will generate new code if the ID already exists, or will exit the loop if the ID is unique and doesn't come up in the database?
Also I'm having trouble with my IDchecker(id) method, I'm using ResultSet to bring back the data from SQL, but I can't find a way to determine how many rows does ResultSet has (if at all). There is no isEmpty() for resultSet?
Here's the code:
public void AddItem() {
boolean checkCode = false;
while (checkCode == false) {
Random r = new Random();
int numbers = 100000 + (int) (r.nextFloat() * 899900);
String ID= Integer.toString(numbers);
try {
if (DatabaseConnection.checkID(ID) == false) {
checkCode = true;
System.out.println("ID is unique");
} else if (DatabaseConnection.checkID(ID) == true) {
System.out.println("ID is NOT unique");
}
} catch (SQLException ex) {
Logger.getLogger(ModelTabeleIntervencija.class.getName()).log(Level.SEVERE, null, ex);
}
}
And here is the ckeckID(ID) method
public boolean CheckID(String ID) throws SQLException {
String query = "SELECT itemId FROM items WHERE itemID= '"+ID+"'";
Statement dbStatement = connection.createStatement();
ResultSet rsItems= dbStatement .executeQuery(query);
if (rsItems.isEmpty( )== true){
return false;
// ID not found - is unique
} else{
return true;
// ID found - is not unique
}
}
Thanks
While generating unique id is best done in your database, I can help you simplify your code. You shouldn't need to check your database twice.
private final Random r = new Random();
public String getUniqueId() {
try {
while (true) {
int n = r.nextInt(1000 * 1000) + 1000 * 1000;
String id = ("" + n).substring(1); // number between 000000 and 999999
if (DatabaseConnection.checkID(id))
return id;
}
} catch (SQLException ex) {
throw new IllegalStateException("Cannot access database", ex);
}
}
However, instead of generating a random id, you could just get the next id.
public String getUniqueId() {
try {
String maxId = DatabaseConnection.selectMaxId();
int n = Integer.parseInt(maxId) + 1;
return ("" + n).substring(1); // number between 000000 and 999999
} catch (SQLException ex) {
throw new IllegalStateException("Cannot access database", ex);
}
}

Categories