net.ucanaccess.jdbc.UcanaccessSQLException: attempt to assign to non-updatable column - java

try{
//taking input from user about how much balance
Scanner input = new Scanner(System.in);
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
String url = "jdbc:ucanaccess://c://Bibek//Atmcard.accdb";
System.out.print("\nConnecting to database...");
con = DriverManager.getConnection(url);
st = con.createStatement();
System.out.println("\n Enter balance you want to withdraw:\n");
balance = Double.parseDouble(input.nextLine());
String sql = "select AccountBalance From Atm";
result = st.executeQuery(sql);
while(result.next()){
//assigning balanceFromDb to deduct and update in database
Double balanceFromDb = result.getDouble("AccountBalance");
balanceFromDb=balanceFromDb-balance;
result.updateDouble("AccountBalance", balanceFromDb);
result.updateRow();
}
}catch(Exception ex){
System.err.println(ex.toString());
}
output: Connecting to database...
Enter balance you want to withdraw:
20
net.ucanaccess.jdbc.UcanaccessSQLException: attempt to assign to non-updatable column

Check the Atm object in the access database and make sure it is a table and not a query. Also check the datatype for AccountBalance and make sure that it is an editable field. If it is auto incremented or calculated you will not be able to update it.
Edit: looks like you have to declare it an update able cursor. Here is the example from ucanacces on source forge http://ucanaccess.sourceforge.net/site.html
Using updatable ResultSet
PreparedStatement ps = super.ucanaccess.prepareStatement( "SELECT * FROM T1", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE, ResultSet.CLOSE_CURSORS_AT_COMMIT);
rs = ps.executeQuery();
rs.next(); 
rs.updateString(2, "show must go off"); 
rs.updateRow();

Related

Java: SQL Query: rs.next() is false after updating a column

I have a strange problem. I have a database and I want to change the values of a column. The values are safed in an Arraylist (timelist).
In order to write the values in the right row, I have a second Arrylist (namelist). So I want to read the first row in my Database, than I check the namelist and find the name. Than i take the matching value out of the timelist and write it into the database into the column "follows_date" in the row, matching to the name.
And than I read the next row of the Database, until there are no more entries.
So the strange thing is, if I change nothing in the database, the while(rs.next()) part works.
For example:
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //liest die namen
}
}
This would print me every name after name. But when I change the table, the while loop ends after that. (no error, the program just finishes)
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //writes the name
//look, if name is in Arraylist "namelist"). if yes, than write the matching date from "timelist" into the database.
if (namelist.contains(name)){
System.out.println("name found: "+ name);
int listIndizi = namelist.indexOf(name); //get index
Long indiziDatum = (long) timelist.get(listIndizi); //get date from same Index
System.out.println(indiziDatum); // print date so i can see it is correct (which it is)
statement.executeUpdate("UPDATE users SET follows_date ="+ indiziDatum +" WHERE username = '"+name+"'"); //updates the follows_date column
}
}
Everything works fine, except that now, the while loop doesn't continues after the first passage, but ends.
The resultSet of a statement is closed and will not return further results if you execute another statement. Create a new separate statement object for the update and everything should work as excepted.
Statement statement1 = connection.createStatement();
Statement statement2 = connection.createStatement();
ResultSet resultSet1 = statement1.executeQuery("SELECT username FROM users");
while(resultSet1.next()){
...
statement2.executeUpdate("UPDATE users ..."));
}
As to Why it happens:
Here is the explanation from the official documentation:
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
Alternative Approach:
From your sample, it seems you are trying to update the "same" row in your resultSet, you should consider using an Updatable ResultSet.
Sample code from the official documentation:
public void modifyPrices(float percentage) throws SQLException {
Statement stmt = null;
try {
stmt = con.createStatement();
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet uprs = stmt.executeQuery(
"SELECT * FROM " + dbName + ".COFFEES");
while (uprs.next()) {
float f = uprs.getFloat("PRICE");
uprs.updateFloat( "PRICE", f * percentage);
uprs.updateRow();
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
}

How to go through all rows in employeeID column in database and retrieve hourly pay rate one at a time?

I have the following sql table called employee_info with two important columns, "employeeID" and "HourlyRate". What I want to do is get the HourlyRate from each employeeID one at a time, do calculations on that and then store it in another database with the same primary key employeeID, and then repeat the whole process for the next employeeID and so on until all are completed.
So far I have tried this very basic incomplete code to try and retrieve the information, but I am unsure how to do the above, help is appreciated, thanks
boolean st = false;
PreparedStatement ps3 = con.prepareStatement("SELECT HourlyRate FROM payroll_system.employee_info");
ResultSet rs = ps3.executeQuery();
st = rs.next();
float hourlyRate = rs.getFloat("HourlyRate");
Test logic:
PreparedStatement ps3 = con.prepareStatement("SELECT HourlyRate FROM payroll_system.employee_info");
ResultSet rs = ps3.executeQuery();
while(rs.next()) {
float hourlyRate = rs.getFloat("HourlyRate");
String employee_id = rs.getString("employeeID");
PreparedStatement ps4 = con.prepareStatement("UPDATE payroll_system.payslip SET basic = ? WHERE employeeID=?");
ps4.setFloat(1, hourlyRate);
ps4.setString(2, employee_id);
ps4.executeUpdate();
}
You need to iterate trough the result-set.
See: https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
rs.first();
while( rs.next() ){
float hourlyRate = rs.getFloat("HourlyRate");
int employeeID = rs.getInt("employeeID ");
//Do your code to calculate and update other database....
//You need to check for INSERT or UPDATE in the other database.
//Make one select on the current tupel
//e.g.
PreparedStatement checkUpdateOrInsert = conOnOtherDb.prepareStatement("SELECT employeeID FROM otherSchema.otherTable");
ResultSet rsCheckUpdateOrInsert = checkUpdateOrInsert .executeQuery();
if( !rsCheckUpdateOrInsert.first() ){
//On onther DB you must insert
}//untested, (bool) first should return false on no row?
else{
//On onther DB you must update
}
}
Thanks for your help guys!
If i understand your question the simple way to do this is to make something like this:
PreparedStatement ps3 = con.prepareStatement("SELECT employeeID, HourlyRate FROM payroll_system.employee_info");
ResultSet rs = ps3.executeQuery();
Statement statement2 = con.createStatement(); // for update query
while(rs.next()){
float hourlyRate = rs.getFloat("HourlyRate");
int employeeID = rs.getInt("employeeID");
//Do calculations
String sql_update = "UPDATE...";
statement2.executeUpdate(sql_update);
}
It should do the trick.
what kind of calculations, do you have to do ? can it be done in sql it self ?
If so,
you can
either
CREATE TABLE payroll_system.cal_hourly_rates as
SELECT employeeID, calculate(hourlyRate) calcRate
FROM payroll_system.employee_info
if payroll_system.cal_hourly_rates is already created
INSERT INTO payroll_system.cal_hourly_rates cal(employeeID, calcRate)
SELECT employeeID, calculate(hourlyRate) calcRate
FROM payroll_system.employee_info einfo
WHERE einfo.employeeID != cal.employeeID

How to take an integer input from a text field and add it to a value in a database

I'm trying to create a banking interface and hence have asked the user to enter a withdrawing amount, which I need to subtract from the amount in the database.
a stores the value entered in the text field.
c needs to get the value stored in the database (seems to not be working).
use.p1.gettext is the password entered by the user to which I'm comparing.
int a=Integer.parseInt(t1.getText());
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/bankdetails","root","password");
String Sql = "select * from users where password = "+use.p1.getText();
Statement stmt = con.createStatement();
rs = stmt.executeQuery(Sql);
int c = rs.getInt("ball");
int b=c-a;
String sql = "insert into users(users,password,ball,s_ball) where password = password "+"value(?,?,?,?)";
pst=con.prepareStatement(sql);
pst.setInt(0,b);
pst.execute();
login_page page=new login_page();
page.setVisible(true);
page.getContentPane();
}
catch(Exception e){
JOptionPane.showMessageDialog(null,e);
}

Reading data from mysql database using java

Firstly, I'm reading the product name and number of products from user using jTextFields. For that product I read the product id and price from database using sql query. But in the below code I display the product price in a jtextField but while running tha file I get query executed successfully but I'm not getting anything in the jtextField.
And please check the sql query and resultset use,
table name is "item" and database name is "myshop",
I declared variables globelly and this code is in a jButton's 'ActionPeformed" part.
String item_name=name.getText();
int item_no=Integer.parseInt(no.getText());
String sql="SELECT id,price FROM item WHERE item.name='item_name'";
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/myshop","root","mysql");
java.sql.Statement stmt=con.createStatement();
if (stmt.execute(sql)) {
rs = stmt.getResultSet();
JOptionPane.showMessageDialog(this, "succes","executed query",JOptionPane.PLAIN_MESSAGE);
} else {
System.err.println("select failed");}
int idIndex = rs.findColumn("id");
int priceIndex = rs.findColumn("price");
while(rs.next()){
item_id=rs.getInt(idIndex);
item_price=rs.getInt(priceIndex);
jTextField1.setText(""+item_price);//displaying product price in a jTextField1
jTextField2.setText(""+item_id);//displaying product id in a jTextField2
}
}
catch(Exception e){
JOptionPane.showMessageDialog(this, e.getMessage());
}
This line should be
String sql="SELECT id,price FROM item WHERE item.name='item_name'";
like this
String sql="SELECT id,price FROM item WHERE item.name='"+item_name+"'";
Use a PreparedStatement so you don't have to worry about delimiting all the variables:
String sql="SELECT id, price FROM item WHERE item.name = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString( 1, item_name);
ResultSet rs = stmt.executeQuery();
Then the prepared statement will replace the variable for you with the proper quotes.
you would need to take item_name as param and put in quotes,
String sql="SELECT id,price FROM item WHERE item.name='"+ item_name+"'";
Try to avoid this type of mistake by using PreparedStatement
String sql="SELECT id,price FROM item WHERE item.name=?";
PreapredStatement ps = con.prepareStatement(sql);
ps.setString(1,item_name);
ResultSet rs = ps.executeQuery();
Use of PreparedStatement also prevent SQL injection attack.
try this code .
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/myshop","root","mysql");
PreparedStatement pt=con.prepareStatement("SELECT id,price FROM item WHERE item.name=?");
pt.setString(1,"item_name");
ResultSet rs;
if(pt.execute())
{
rs=pt.getResultSet();
JOptionPane.showMessageDialog(this, "succes","executed query",JOptionPane.PLAIN_MESSAGE);
}
else {
System.err.println("select failed");
}
while(rs.next()){
item_id=rs.getInt(1);
item_price=rs.getInt(2);
jTextField1.setText(""+item_price);//displaying product price in a jTextField1
jTextField2.setText(""+item_id);//displaying product id in a jTextField2
}
First, you need an reader, like this
private static void reader() throws SQLException {
DataBaseName db = new DataBaseName ();
names = db.getNames();
}

Operation not allowed after ResultSet Closed error Netbeans MySQL Connectivity

I am creating a program to rename databases in mysql.
I have succeeded in everything and it successfully happens. But in the end of my script, its shows an error/exception saying "Operation not allowed after ResultSet closed". I really have no idea why this error appears even after researching about this error.
Although the full operation is successfully completed and the database is renamed.
Here is my code->
String x = (String) jComboBox1.getSelectedItem(); //jComboBox1 contains the name of current database selected
String z = JOptionPane.showInputDialog("Please enter new name for Database"); //Where user enters the name for new database.
new CustComm().setVisible(false); //Frame that carries the names of tables.
try{
Class.forName("java.sql.DriverManager");
Connection con = (Connection)
DriverManager.getConnection("jdbc:mysql://localhost:"+GlobalParams.portvar+"/",""+k,""+j);
Statement stmnt = (Statement) con.createStatement();
String query = "use "+x;
stmnt.executeQuery(query);
String query2 = "show tables";
ResultSet rs = stmnt.executeQuery(query2);
while (rs.next()){
String dname = rs.getString("Tables_in_"+x);
if(CustComm.jTextArea1.getText().equals("")){
CustComm.jTextArea1.setText(CustComm.jTextArea1.getText()+dname);
}
else{
CustComm.jTextArea1.setText(CustComm.jTextArea1.getText()+"\n"+dname);
}
String y = CustComm.jTextArea1.getText();
Scanner scanner = new Scanner(y);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String query3 = "Create database "+z;
stmnt.executeUpdate(query3);
//alter table my_old_db.mytable rename my_new_db.mytable
String query4 = "RENAME TABLE "+x+"."+line+" TO "+z+"."+line;
stmnt.executeUpdate(query4);
String query5 = "drop database "+x;
stmnt.executeUpdate(query5);
}}}
catch(Exception e){
JOptionPane.showMessageDialog(this,e.getMessage());
}
Please help.
You shouldn't execute new queries on statement Statement stmnt = (Statement) con.createStatement(); while you use ResultSet from it, because this will close your ResultSet.
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects. All execution methods in the Statement
interface implicitly close a statment's current ResultSet object if an
open one exists.
You should create 2 different statements: first for query2 and second for queries 3-5.
Also it's better to use PreparedStatement. You can read about the difference here.
Do you have to do this work via code? Have you looked into tools like Liquibase?

Categories