I have tried to research this problem however I cannot find a solution.
Background: I have a small java program using sqlite as its DB. I am trying to update a row counter to keep track of how many time a code is searched, or how many times a row is displayed. (If a row is not displayed it will not be counted). My database table hase three columns {Codes, Description, ItemCount}
Here is code that I used to get a row
private void SrchCodeActionPerformed(java.awt.event.ActionEventevt) {
String sql = "SELECT * FROM emdcodes WHERE Codes like ?"; // SQL command
try {ps = conn.prepareStatement(sql);
ps.setString(1, EMDCODELOOKUP.getText() + "%");
rs = ps.executeQuery();
ResultsTable.setModel(DbUtils.resultSetToTableModel(rs));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
} }
I am using this sql code on a website version and it works. it is written in PHP.
$sqlcount = mysql_query("update emdcodes SET ItemCount = ItemCount +1 Where Codes like '$term%'");
My Question is where and how would I add the counter code to the java progam. The purpose of the counter is to maintain a list of the top 5 items searched for.
I thank anyone for their help.
I am not sure if this is exactly what are you looking for...
private void SrchCodeActionPerformed(java.awt.event.ActionEventevt) {
if (counter <= 5) {
String sql = "SELECT * FROM emdcodes WHERE Codes like ?"; // SQL command
try {ps = conn.prepareStatement(sql);
ps.setString(1, EMDCODELOOKUP.getText() + "%");
rs = ps.executeQuery();
if (rs.first()){
counter++;
}
ResultsTable.setModel(DbUtils.resultSetToTableModel(rs));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
}
first() ->
Moves the cursor to the first row in this ResultSet object.
Returns:
true if the cursor is on a valid row; false if there are no rows in the result set
Related
Good day, just wanna ask. I have a Java GUI where I want to add multiple data from SQL server to my Jtable. The flow here is that I would want to use the text field as search field where I will add the info for searching and use the Jbutton to perform the search action then it will give/show me the data to my Jtable. Actually the code is running however some of the data like the 1st data added to my SQL serve and from data id 7 and and up are not showing. How would I fix this and show multiple data with same order ID form SQL server?
Thank you!!
try {
String query = "select * from `sales_product` where order_id = ?";
pst = con.prepareStatement(query);
pst.setString(1, txsearch.getText());
ResultSet rs = pst.executeQuery();
if(rs.next()) {
while(rs.next()) {
String prodname = rs.getString("prodname");
String price = String.valueOf(rs.getInt("price"));
String qty = String.valueOf(rs.getInt("qty"));
String total = String.valueOf(rs.getInt("total"));
model = (DefaultTableModel) datatable.getModel();
model.addRow(new Object[]{
prodname,
price,
qty,
total
});
int sum = 0;
for (int a = 0; a < datatable.getRowCount(); a++) {
sum = sum + Integer.parseInt(datatable.getValueAt(a, 3).toString());
}
Ltotal.setText(Integer.toString(sum));
}
}
else {
JOptionPane.showMessageDialog(this, "No order found!");
txsearch.setText("");
}
} catch (SQLException ex) {
Logger.getLogger(milktea.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(rs.next()) {
while(rs.next()) {
No need for the if (rs.next()) statement. That is causing you to skip the first row of data in the ResultSet.
All you need is the while (rs.next()) statement to create the loop to read all rows in the ResultSet.
I created a system in which I can run all my postgre sql queries with only one single Async Task Class in Android Studio. This was really(!!) challenging due to the big amount of limitations that I had to face. But this works actually really great!
//Used for connecting to database and executing queries.
//Index 0 of input string must be the query, Index 1 must be the tablename we demand
//We can only gather data from 1 table for each query, so if you need data from several tablecolumns, use multiple queries like:
//[0] = query, [1] = tablename, [2] = 2nd query, [3] = 2nd tablename, [4] = 3rd query, [5] = 3rd table name ... and so on (each query must come with a tablename)
public class DBHandler extends AsyncTask<String, Void, List<String>>
{
public AsyncResponse delegate;
#Override
protected List<String> doInBackground(String...query)
{
List<String> result = new ArrayList<String>();
String sql;
String tableresult = null;
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
Class.forName("org.postgresql.Driver");
conn = DriverManager.getConnection("jdbc:postgresql://192.168.200.300:5439/dbname?user=anonymous&password=secretpw");
st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); //necessary if you want to use rs.first() after rs.next(), it makes the resultset scrollable
for (int i = 0; i <= query.length-1; i = i+2) //queries are always stored in i=0 and/or in i+2, because i+1 contain the demanded tablenames for resultset handling
{
System.out.println("I is: " +i);
if (!query[i].isEmpty())
{
System.out.println(query[i]);
sql = query[i];
rs = st.executeQuery(sql);
while (rs.next())
if (!query[i + 1].isEmpty() || !rs.getString(query[i + 1]).isEmpty()) //if i+1 is empty, there is no demanded tablename. Used when we dont need any return values (ie. INSERT, UPDATE)
result.add(rs.getString(query[i + 1])); //demanded tablename is always stored in i+1
//We add an empty entry if we demand multiple tablenames so we can keep them seperate
//Might be replaced with any other char, but you will have to backtrack all usages of DBHandler and fix the filters there
if(i+2 < query.length)
result.add(" ");
}
rs.first(); //reset pointer for rs.next()
}
rs.close();
st.close();
conn.close();
System.out.println("End of AsyncTask");
}
catch (SQLException ex)
{
ex.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}
//onPostExecute returns query result in a List.
//We need to use interaces delegate feature to send the result to other classes, like "Auslieferung", which is implementing the interface
#Override
protected void onPostExecute(List<String> result)
{
super.onPostExecute(result);
System.out.println("Result: " +result.toString());
if (!result.isEmpty())
delegate.processFinish(result);
}
}
There is a for-loop in this Async Task.
for (int i = 0; i <= query.length-1; i = i+2)
And now finally I can explain my issue:
I usually use SELECT queries, sometimes I use an INSERT query (which can be done by a single query), but when I parse an Update Query, my for-loop stops iterating after the first pass, so i+2 never happens. The update queries look like this:
String updatequeries[] = {UPDATE delivery SET contactperson = 'Jon Doe' WHERE officeid = 5, " ", UPDATE delivery SET contactemail = 'abd#def.gh' WHERE officeid = 5, " "};
Why does this for loop stop running right after the first run? The debugger does not show anything unusual, everything was parsed right and there are no queries missing. Updating a table does not return any results, but nothing depends on result values here. I tried to run 20 update queries in a single string var, but the for loop stops after the first iteration anyway. No issues are displayed in the debugger or in the logs. Have I overseen something or is there anything I don't know? Might this be a bug? Please help me! This issue drives me crazy.
I have read a similar post but I still cannot get what is the problem.
I created a table in ms access, named DOCTOR, there are columns: DoctorID(number), Name(text), PhoneNumber(number), Department(text) and Specialization(text)
I connect the database to java through UCanAccess, below is the code to get connection
import java.sql.*;
public class Doctor
{
public static Connection connection; //sharing the memory
public static Connection connect() throws ClassNotFoundException, SQLException
{
String db = "net.ucanaccess.jdbc.UcanaccessDriver";
Class.forName(db);
String url = "jdbc:ucanaccess://C:/Users/user.oemuser/Documents/Doctor.accdb";
connection = DriverManager.getConnection(url);
return connection;
}
}
In my GUI class, i have a method called getConnect to show the data from database to textfield
public void getConnect()
{
try
{
connection = Doctor.connect();
statement=connection.createStatement();
String sql = "SELECT * FROM DOCTOR";
results = statement.executeQuery(sql);
results.next();
id = results.getInt("DoctorID");
name = results.getString("DoctorName");
phone = results.getInt("PhoneNumber");
dept = results.getString("Department");
spec = results.getString("Specialization");
textField1.setText("" +id);
textField2.setText(name);
textField3.setText("" +nf3.format(phone));
textField4.setText(dept);
textField5.setText(spec);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
and below is the code for the button1 which is the next button.
if(evt.getSource() == button1)
{
try
{
connection = Doctor.connect();
connection.setAutoCommit(false);
statement=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
String sql1 = "SELECT * FROM DOCTOR";
results = statement.executeQuery(sql1);
if(results.next())
{
textField1.setText("" +results.getInt("DoctorID"));
textField2.setText(results.getString("DoctorName"));
textField3.setText("" +nf3.format(results.getInt("PhoneNumber")));
textField4.setText(results.getString("Department"));
textField5.setText(results.getString("Specialization"));
}
else
{
results.previous();
JOptionPane.showMessageDialog(null, "No more records");
}
connection.commit();
}
catch(Exception ex){
ex.printStackTrace();
}
}
Obviously the best component to use here is a JTable if you want to query all records within a particular database table or at the very least place the result set into an ArrayList mind you database tables can hold millions+ of records so memory consumption may be a concern. Now, I'm not saying that your specific table holds that much data (that's a lot of Doctors) but other tables might.
You can of course do what you're doing and display one record at a time but then you should really be querying your database for the same, one specific record at a time. You do this by modifying your SQL SELECT statement with the addition of the WHERE clause statement and playing off the ID for each database table record, something like this:
String sql = "SELECT * FROM DOCTOR WHERE DoctorID = " + number + ";";
But then again we need to keep in mind that, if the schema for your DoctorID field is set as Auto Indexed which of course allows the database to automatically place a incrementing numerical ID value into this field, the Index may not necessarily be in a uniform sequential order such as:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,.......
instead it could possibly be in this order:
1, 3, 4, 5, 6, 9, 10, 11, 16, 17,....
This sort of thing happens in MS Access Tables where a table record has been deleted. You would think that the ID slot that is deleted would be available to the next record added to the table and would therefore hold that removed ID value but that is not the case. The Auto Index Increment (autonumber) simply continues to supply increasing incremental values. There are of course ways to fix this sequencing mismatch but they are never a good idea and should truly be avoided since doing so can really mess up table relationships and other things within the database. Bottom line, before experimenting with your database always make a Backup of that database first.
So, to utilize a WHERE clause to play against valid record ID's we need to do something like this with our forward and reverse navigation buttons:
Your Forward (Next) Navigation Button:
if(evt.getSource() == nextButton) {
try {
connection = Doctor.connect();
connection.setAutoCommit(false);
number++;
long max = 0, min = 0;
ResultSet results;
Statement statement=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
// Get the minimum DoctorID value within the DOCTOR table.
String sql0 = "SELECT MIN(DoctorID) AS LowestID from DOCTOR";
results = statement.executeQuery(sql0);
while (results.next()){ min = results.getLong("LowestID"); }
// Get the maximum DoctorID value within the DOCTOR table.
sql0 = "SELECT MAX(DoctorID) AS HighestID from DOCTOR";
results = statement.executeQuery(sql0);
while (results.next()){ max = results.getLong("HighestID"); }
if (max <= 0) {
JOptionPane.showMessageDialog(null, "No records found in Doctor Table.");
return;
}
if (number > min) { previousButton.setEnabled(true); }
if (number > max) {
nextButton.setEnabled(false);
JOptionPane.showMessageDialog(null, "No more records");
number--;
}
results = null;
while (results == null) {
String sql1 = "SELECT * FROM DOCTOR WHERE DoctorID = " + number + ";";
results = statement.executeQuery(sql1);
long id = 0;
// Fill The GUI Form Fields....
while (results.next()){
//id = results.getLong("DoctorID");
textField1.setText("" +results.getInt("DoctorID"));
textField2.setText(results.getString("DoctorName"));
textField3.setText("" + results.getString("PhoneNumber"));
textField4.setText(results.getString("Department"));
textField5.setText(results.getString("Specialization"));
connection.commit();
return;
}
// ----------------------------------------------------------
if (id != number) { results = null; number++; }
}
}
catch(Exception ex){ ex.printStackTrace(); }
}
Your Reverse (Previous) Navigation Button:
if(evt.getSource() == previousButton) {
try {
connection = Doctor.connect();
connection.setAutoCommit(false);
number--;
long max = 0, min = 0;
ResultSet results;
Statement statement=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
// Get the minimum DoctorID value within the DOCTOR table.
String sql0 = "SELECT MIN(DoctorID) AS LowestID from DOCTOR";
results = statement.executeQuery(sql0);
while (results.next()){ min = results.getLong("LowestID"); }
// --------------------------------------------------------------------------
// Get the maximum DoctorID value within the DOCTOR table.
sql0 = "SELECT MAX(DoctorID) AS HighestID from DOCTOR";
results = statement.executeQuery(sql0);
while (results.next()){ max = results.getLong("HighestID"); }
// --------------------------------------------------------------------------
if (max <= 0) {
JOptionPane.showMessageDialog(null, "No records found in Doctor Table.");
return;
}
if (number < min) {
previousButton.setEnabled(false);
JOptionPane.showMessageDialog(null, "No more records");
number++;
}
if (number < max) { nextButton.setEnabled(true); }
results = null;
while (results == null) {
String sql1 = "SELECT * FROM DOCTOR WHERE DoctorID = " + number + ";";
results = statement.executeQuery(sql1);
long id = 0;
// Fill The GUI Form Fields....
while (results.next()){
textField1.setText("" +results.getInt("DoctorID"));
textField2.setText(results.getString("DoctorName"));
textField3.setText("" + results.getString("PhoneNumber"));
textField4.setText(results.getString("Department"));
textField5.setText(results.getString("Specialization"));
connection.commit();
return;
}
// ----------------------------------------------------------
if (id != number) { results = null; number--; }
}
}
catch(Exception ex){ ex.printStackTrace(); }
}
Things To DO...
So as to remove duplicate code, create a method named
getMinID() that returns a Long Integer data type. Allow this method to accept two String Arguments (fieldName and
tableName). Work the above code section used to gather the minimum DoctorID value within the DOCTOR table into the new
**getMinID() method. Use this new method to replace the formentioned code for both the Forward (Next) and Revese (Previous)
buttons.
So as to remove duplicate code, create a method named
getMaxID() that returns a Long Integer data type. Allow this method to accept two String Arguments (fieldName and
tableName). Work the above code section used to gather the maximum DoctorID value within the DOCTOR table into the new
getMaxID() method. Use this new method to replace the formentioned code for both the Forward (Next) and Revese (Previous)
buttons.
So as to remove duplicate code, create a void method named
fillFormFields(). Allow this method to accept two arguments, one as Connection (*connection) and another as ResultSet
(results) . Work the above code section used to Fill The GUI
Form Fields into the new fillFormFields() method. Use this new
method to replace the formentioned code for both the Forward (Next)
and Revese (Previous) buttons.
Things To Read That Might Be Helpful:
The SQL WHERE clause statement and the SQL ORDER BY statement for sorting your result set.
Searching For Records
private void btgetinvActionPerformed(java.awt.event.ActionEvent evt) {
//JOptionPane.showMessageDialog(null, "REMITTANCE ID IS VALID!");
try {
DBUtil util = new DBUtil();
Connection con = util.getConnection();
PreparedStatement stmt = con.prepareStatement("select bk_det.rm_id from bk_det WHERE dbo.bk_det.rm_id = ?");
ResultSet rs;
String rm = tf_rmid.getText().trim();
stmt.setInt(1, Integer.parseInt(rm));
rs = stmt.executeQuery();
while (rs.next()) {
int i = Integer.parseInt(rs.getString("box_no"));
tfbrname.setText(rs.getString(i));
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
I am actually trying to search value from my database table called dbo.bk_det. I am taking the value of WHERE from my textfield tf_rmid. Everything goes on well without error but once i insert the rm_id and click on button btgetinv it says 123 which is my rm_id is out of range cant understand where the error is and what is the problem.
The problem is with the following statements:
int i = Integer.parseInt(rs.getString("box_no"));
tfbrname.setText(rs.getString(i));
The first statement won't work the way you want because there's no column named "box_no" in the select clause. It will throw an exception. Let's assume you change the code to have box_no in the select clause. Then, the second statement will try to retrieve the nth column where the column is the value of box_no. I think you just want:
tfbrname.setText(rs.getString("box_no"));
Again, the above only will work if your SELECT statement includes box_no in the field list.
rs.next() returns false if it does not contain any more records. So if you want to behave something when no records found, you have to check record count.
for example,
int recordCount = 0;
while (rs.next()) {
recordCount++;
int i = Integer.parseInt(rs.getString("box_no"));
tfbrname.setText(rs.getString(i));
}
if(recordCount == 0) {
// do something : report an error or log
}
for further information, see http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#next()
So I'm having issues with my program. Basically this far the program is like a MySQL based chat. It stores messages in database and reads them. I'm having problems with the reading. What it does right now is ever 5 seconds re-read all the messages in the database. I tried to make it read only the new messages but that's not working out too well. This is my code:
public static void readChat()
{
try
{
MySQL.sqlConnect();
try
{
Statement st = con.createStatement();
ResultSet res = st.executeQuery("SELECT * FROM table1");
while (res.next())
{
if (lastLine < res.getInt("id"))
{
String message = res.getString("message");
Gui.out.append(message + "\n");
lastLine = res.getInt("id");
}
}
}
catch (SQLException s)
{
System.out.println("SQL code does not execute.");
}
MySQL.sqlDisconnect();
}
catch (Exception e)
{
e.printStackTrace();
}
}
I'm not sure how to make this efficient. It takes way too long to execute that. If the id is 23 I can't even see the messages appear because it takes longer than 5 seconds. I added the
if (lastLine < res.getInt("id"))
and
lastLine = res.getInt("id");
in my effort to make it read only the new messages but it did not work as expected. I think it still executed line by line, just doesn't show it in the chat. There's got to be an easier way.
EDIT: Alright, so I fixed the problem with not seeing messages, (I forgot to remove the part of the code that cleared the chat every 5 seconds). But it still takes a long time to send messages, about 3-4 seconds?
Try this, and you will wonder :)
ResultSet res = st.executeQuery("SELECT * FROM table1 where id > "+lastLine);
instad
ResultSet res = st.executeQuery("SELECT * FROM table1");
and get result without if
while (res.next())
{
String message = res.getString("message");
Gui.out.append(message + "\n");
lastLine = res.getInt("id");
}
Of course make sure index on id field
you can just read the required rows, currently you are reading all the rows try following,
public static void readChat()
{
try
{
MySQL.sqlConnect();
try
{
Statement st = con.Preparestatment("SELECT * FROM table1 where id > ?");
st.setInt(0,lastLine);
ResultSet res = st.executeQuery();
while (res.next())
{
String message = res.getString("message");
Gui.out.append(message + "\n");
lastLine = res.getInt("id");
}
}
catch (SQLException s)
{
System.out.println("SQL code does not execute.");
}
MySQL.sqlDisconnect();
}
catch (Exception e)
{
e.printStackTrace();
}
}
You still iterate through all results. If you have some way of storing the time at which messages are sent i.e creating a time column, you can try to shorten how many results are returned by doing
ResultSet res = st.executeQuery("SELECT * FROM table1 WHERE id = ? AND time > ?");
where the first ? is the id of the user and the 2nd ? is the time of the last read message. This is based off the assumption id is some unique user id.
What about maintaining a list, add new message to that list when you save it to the database and just read the new messages from that list and clear it at the end of readChat()?