Increasing an ID_Column value by 1 with mysql - java

I wrote this code which increases a jlabel content by 1.
this works perfectly with SQLite database. but when I switched to MySQL, the same syntax produces no value at all. please what seems to be the problem. the code is as follows:
try{
String sql = "Select max(ID) from ad_form";
pst=con.prepareStatement(sql);
rs=pst.executeQuery();
String one =rs.getString("max(ID)");
id.setText(one);
int all = Integer.valueOf(id.getText());
all=all+1;
id.setText(String.valueOf(all));
}catch(SQLException | NumberFormatException e ){
JOptionPane.showMessageDialog(null,e);
}
finally{
try{
rs.close();
pst.close();
}
catch(Exception ep){
ep.getMessage();
}
}
anytime the code runs, the jlabel which is to display the value is blank.

The issue is the naming of the unnamed expression. This is going to vary by database. So simply do:
Select max(ID) as max_id from ad_form
and then:
String one =rs.getString("max_id");
This will work in any database.
I am concerned about fetching the maximum id. If your desire is to increment it by one and use it for a subsequent insert, then this is the wrong approach. Instead, you should be using an auto_increment column.

Related

How to fix 'terminated' while using rs.getString

When trying to pull from an SQL database, I get in Java console.
I am able to enter my ID manually in the prepareStatement, but I can't use setString to work with with the prepareStatement.
I haven't throught of too much to try, but I did find that the issue is within the while statement. rs.next returns false when it should return true. The information in SQL has been committed, and I can call all of the information in java using a function that reads out the entire table.
getemployeeDataById("01");
private static void getemployeeDataById(String e_id) {
DBConnection dbConnection = DBConnection.getInstance();
PreparedStatement ps;
try {
ps = dbConnection.getConnection().prepareStatement("select * from employee where E_ID = ?");
ps.setString(1, e_id);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("ename"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
SQL
CREATE TABLE EMPLOYEE
(E_ID CHAR(3) PRIMARY KEY,
ENAME CHAR(25),
DOB CHAR(25),
EMAIL CHAR(25),
PHONE CHAR(25),
ADDRESS CHAR(25));
INSERT INTO EMPLOYEE
VALUES
('01','JEREMY MANN','12/23/1992','jeremy#jeremy.com','317-528-1234','123 CandyCane Lane');
I am expecting to get the name outputted in the console, so for this example it would be "JEREMY MANN." The code runs and then in the Eclipse Java console it shows Application [Java Application]. It runs into an issue within the while statement, but I'm not sure what's causing rs.next to be false.
In Oracle 11g (well, Oracle versions generally) CHAR is a fixed width type, and if you give it a value shorter than the given width, it will be padded with blanks (which might not be obvious if you just dumped the table contents). In this case, your key is length 3, but the string "01" is length 2, so that won't work.
Try VARCHAR2 for the column types, that's a variable length string.

Code executing time is incredibly long

I'm trying to move data from one table to another(both table are same basically), the method that I'm using is INSERT-SELECT.
The problem that I'm facing is my java program seem like frozen there, but I can still force close it with ^C easily, so I think it might be still alive but stuck for some reason.
This is my code which stuck in this problem
public String moveData(String sql, int day) {
Connection con = null;
PreparedStatement stmt = null;
int count;
try {
con = DriverManager.getConnection(DSN, Username, Password);
stmt = con.prepareStatement(sql);
stmt.setInt(1, day);
count = stmt.executeUpdate();
return String.valueOf(count);
} catch (SQLException e) {
System.out.println("SQL exception: " + e.getMessage());
e.printStackTrace();
return "false";
} finally {
try {
stmt.close();
} catch (Exception e) {
}
try {
con.close();
} catch (Exception e) {
}
}
}
and the SQL, executing it in SQL developer is really fast with 0.231 sec for 23k row of data
insert into Request_History (customer_id, request_id, status, transaction_date, last_modified)
SELECT customer_id, request_id, status, transaction_date, current_timestamp
from Request_Log
where transaction_date <= (sysdate - NUMTODSINTERVAL(:1 ,'DAY'))
I see no problem on them, is there anything that I missed?
Update
Since there's no resolve on the program and SQL command, I'd like to change a way of thinking on the DB side.
Could anyone please tell me what kind of privileges do I need to execute my INSERT-SELECT SQL command on 11g without problem? because from what I can see that this command would only needs basic privileges such as SELECT/INSERT/UPDATE/DELETE to execute.
The time of the whole insert process depends on three factors:
How many rows are in the query result set
Is there any index, which can be used at query level (best for this would be an index on Request_Log.transaction_date
Are there any constraints, indexes which have to be maintained during the insert phase (Request_History table)
Check the exec plan of the statement, to see if there's anything - worst things are full table scans. If you allowed, you can paste here the execution plan as well.
there is probably something wrong with the way you open your connection, something with you session parameters. You might not have enough undo space or another limiting factor. Maybe you can get a dba to check on it while you execute this over java vs. SQL Developer.
alter you statement to
create table Request_History_test
as SELECT
customer_id, request_id, status, transaction_date, current_timestamp
from
Request_Log
where
transaction_date <= (sysdate - NUMTODSINTERVAL(:1 ,'DAY'))
if this goes fast in contrast to your "insert select", then contact your DBA. There might be known issues with your undo space / redo logs. I'm not a DBA, so this answer is vague, I just had similar problems once.
oh, and check your dba_hist_sqlstat to see where the time is lost.

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.

Resultset not open

I get following error on Result set
java.sql.SQLException: ResultSet not open. Verify that autocommit is OFF.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.ResultSet.next(Unknown Source)
public ResultSet insertDb(int Id,String firstName,String lastName,String title) throws SQLException{
try {
try {
Class.forName(driver);
con = DriverManager.getConnection(connectionURL);
} catch (SQLException ex) {
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(con.getAutoCommit());
statement = con.createStatement() ;
res = statement.executeQuery("SELECT * FROM CUSTOMER") ;
con.setAutoCommit(false);
System.out.println(con.getAutoCommit());
while(res.next()){
if(res.getString("ID").equalsIgnoreCase(Integer.toString(Id))){
UNIQUE = false;
error= "Duplicate Entry Found Please Enter New Data";
throw new SQLException("Duplicate info<br>ID " + Id );
}
}
// IF value to be added IS UNIQUE
if(UNIQUE){
String qry1= "insert into CUSTOMER(ID, FIRSTNAME,LASTNAME,TITLE) values(?,?,?,?)";
stm = con.prepareStatement(qry1);
String ID=Integer.toString(Id);
stm.setString(1, ID);
stm.setString(2, firstName);
stm.setString(3, lastName);
stm.setString(4, title);
stm.executeUpdate();
}
}
catch(Exception e){
String errorMessage = "Exception caught : ";
System.out.println(errorMessage + e.toString());
}finally{
if (con != null){
con.close();
}
}
return res;
}
Try moving the setAutoCommit() and getAutoCommit() to before you create and execute the statement. Changing it after you execute the statement may be invalidating the query.
The problem is that you have closed your query before reading your resultset. Closing the query, closes the resultset, hence why you get the "ResultSet not open" error. You should close the query right at the end, in a finally block:
i.e. con.setAutoCommit(false);
will close the query and along iwth it it closes the resultset also.
Not strictly related, but your code probably doesn't do what you expect. This kind of read-modify-write code doesn't work well when there are multiple concurrent invocations.
If you imagine two invocations running though the code, it becomes clear that sometimes, depending on the execution order, BOTH invocations could reach the insert statement.
In addition, selecting from a table without using a WHERE clause is not generally useful. In this case you select '*', then iterate over all the results to see if "ID" == Id. The database is much much better at that than java is. You should add a where clause. (Note that this still won't solve the above problem)
Its also generally a bad idea to 'select *' from any table. Just pick the columns that you need. This will 'fail fast' if the schema changes and the columns that you need are no longer available, and will allow the database optimiser to do the 'right thing' about its disk accesses.
Finally, if its just a numeric ID that you are looking to assign, its normal practice to use 'autonumber' for these, rather than get the program to pick them. Different databases call them different things, so you might also know them as IDENTITY, or have to use a sequence.
In case it helps anyone down the line, I had the same error with Derby 10.5.1.1 that turned out to be a bug in the driver itself that would appear some times and not others depending on the underlying data. Upgrading the driver to a newer version (10.8.2.2) resolved the problem.

sql cleanup function. rows doesnt get really deleted

i am using java sqlite (org.sqlite.JDBC) with this i am adding a new row of data to the table, one field is supposed to take up a big amount of base64 encoded data (like pdf) the type of this field is sql-TEXT. now, if i delete the row with "DELETE FROM table WHERE id='id'" the row gets deleted as expected, my sqlite browser confirms this. but the table was befor the deletion like 4KB big, after adding the row it was 12MB and after deleting it remains 12MB big. is there a kind of cleanup i have to do?
in sqlite admin(http://sqliteadmin.orbmu2k.de/) there is a "Cleanup" button after pressing that everything is fine, which means the database shrinks to its size befor adding stuff (4KB). after asking google i realy cannot find such a sql command. it seems that only the index informations get deleted from my databasefile, not the content itself. this behavior is known from windows delete functions.
beside that, here is the java snippet i use:
public void deleteRowById(String table, int id){
try {
Connection connection = null;
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:C:\\meinedb");
//statement = connection.createStatement();
String sql = "DELETE FROM "+table+" WHERE id='"+id+"'";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.executeUpdate();
pstmt.close();
connection.close();
} catch (SQLException ex) {
Logger.getLogger(FileSpinner.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex){
}
}
You can shrink a SQLite database with the VACUUM statement. Read the manual I link to for details.

Categories

Resources