JDBC getDouble returns 0.0 - java

I am new to Java and JDBC.
I am trying to get a double value from a database through JDBC and make a global variable equal to that value. Here's what I did.
public class Console {
String sql;
Statement stmt;
Connection conn;
ResultSet rs;
//Category Total
public static double num;
public Console(){
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting to database...");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/database?autoReconnect=true&useSSL=false","user","password");
stmt = conn.createStatement();
System.out.println("Connected database successfully...");
sql = "SELECT sum(a) FROM table";
while(rs.next()) {
rs = stmt.executeQuery(sql);
num = rs.getDouble("sum(a)");
}
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
System.out.println(num);
}
}
When I run the program it prints 0.0 although the actual value is not.

You need to get your result set prior to the while loop, and then iterate through it
rs = stmt.executeQuery(...);
while (rs.next()) {
// and process your results row by row here...
}
Otherwise (as you've discovered) your rs variable is unset
Your result set won't contain sum(a) as a column name. You can get the result positionally (e.g. getInt() can take an index integer) or rename your result column (e.g. select sum(a) as sum FROM table) and reference it like that.

You haven't intialized the ResultSet with executing the query. Then you can loop the result set.
sql = "SELECT sum(a) FROM table";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
num = rs.getDouble("sum(a)");
}
You have been getting the results in the loop, but you have to do it before reach the loop.

You are getting 0.0 because of the behavior of JDBC driver.
From java doc
Returns: the column value; if the value is SQL NULL, the value
returned is 0
To know that last read value was null from Resultset, you can use method rs.wasNull() method. it will return true if the last column value read was SQL NULL and false otherwise.

It's good practice to assign a column alias to calculated results like sum(a) and retrieve the values using that alias.
Also good practice is to use Java's try-with-resources.
The try-with-resources statement ensures that each resource is closed at the end of the statement.
Also, if your SQL statement would return NULL, e.g. in case the table is empty or no rows apply to the conditions in your WHERE clause, the ResultSet.getDouble method will return the value 0.
sql = "SELECT sum(a) AS sum_a FROM table"; // assign alias sum_a to the expression sum(a)
try( ResultSet rs = stmt.executeQuery( sql ) ) { // get a resultset object in a try-with-resources statement, to auto-close it at the end
rs.next( ); // for the query you have, checking if there's a next row is actually not necessary; there's always a result for your query
num = rs.getDouble("sum_a"); // retrieve the column value by its alias
} // rs will be closed for you at this point

Related

How to use textfield input in mysql SELECT query

I am using Java netbeans and mysql. I want to check whether the value entered by the user in a textfield tf is already present in the mysql table or not.
String query1="SELECT * FROM trytable WHERE name='8'";
ResultSet rs=stmt.executeQuery(query1);
if(rs.isBeforeFirst()==true){JOptionPane.showMessageDialog(null,"already");}
In the above code in place of 8 I want to give the value that the user input in the form and then check whether that value already exist in form or not.
Please help me in the first line . Thanks
You should use a PreparedStatement instead of a regular statement. This is more secure than a normal Statement and allows you to avoid SQL injection issues.
You would change your query like so:
String query = "SELECT * FROM trytable WHERE name='?';";
Note the ? at the end of the query. This can be replaced later in your code when setting up the PreparedStatement:
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, userInput);
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) System.out.println("Record exists!");
Here, you are telling the prepared statement to replace the first ? in the query, with the value of userInput. So, if the user inputs a 3, the query that gets executed would be SELECT * FROM trytable WHERE name=3;.
Also note that rs.next() returns true if the query returns any results, so that would be the proper way to determine if the record exists.
ResultSet is like a table, it has a cursor. At the beginning the cursor is above the first row so isBeforeFirst() will always return true even there are no results in the ResultSet.
In order to retrieve results you need to move the cursor to the next row, to do that you can use,
rs.next()
If the cursor moved to the next row successfully (which means there are more results) it will return true otherwise false. As you only need the first result you can also use,
rs.first()
to confirm there are data available in the returned ResultSet.
Try,
if (rs.first()) {
JOptionPane.showMessageDialog(null, "already");
}
This is the final code will is working absolutely fine.
try{
Class.forName("com.mysql.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql","root","");
String query = "SELECT * FROM table_name WHERE name=?;";
PreparedStatement preparedStatement = conn.prepareStatement(query);
preparedStatement.setString(1,jtf.getText());
ResultSet rs = preparedStatement.executeQuery();
if(rs.next()==true){
JOptionPane.showMessageDialog(null,"Value already exist");
}
else{
JOptionPane.showMessageDialog(null,"Value not present");
String query1="INSERT INTO table_name(col_name) VALUES (?)";
preparedStatement = conn.prepareStatement(query1);
preparedStatement.setString(1,jtf.getText());
preparedStatement.execute();
JOptionPane.showMessageDialog(null,"DONE");
}
rs.close();
preparedStatement.close();
}
catch(Exception e){
System.out.println("Exception:"+e.getMessage());
}

rs.next() is returning false in while statement

So, I'm trying to extract msgID and msgStatus values from database for each reference Id(variable msgRefList) stored in the list object and I'm trying to store these extracted values in String objects for further processing. But rs.next() method is returning false and hence it is not going into the while loop where the assignment statements are. I checked in database with the query that i'm using in the code and it shows one record in the result, but still rs.next() is returning false. Screenshot attached with the database results.
Below is the actual code that i'm using
List<String> msgRefList = listofRefrnceValues:
try {
Connection connect = connectToDB(ENV);
for(String reference: msgRefList){
String query="select ID, MSG_STS from TABLE where INSTR_ID = ?";
PreparedStatement stmt = connect.prepareStatement(query);
stmt.setString(1,reference);
ResultSet rs = stmt.executeQuery();
if(rs!=null){
while(rs.next()) {
P_MID = rs.getString("P_MID");
P_MSG_STS = rs.getString("P_MSG_STS");
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
You have some typos in your SQL-Query-String in java. Instead of TABLE you probably meant MINF (your real table) also all of your properties don't have the prefix P_ and ID is probably MID. So change:
String query="select ID, MSG_STS from TABLE where INSTR_ID = ?";
To:
String query="select P_MID, P_MSG_STS from MINF where P_INSTR_ID = ?";
And you'll be fine.

java.sql.SQLException: Operation not allowed after ResultSet closed [help] [duplicate]

When I execute the following code, I get an exception. I think it is because I'm preparing in new statement with he same connection object. How should I rewrite this so that I can create a prepared statement AND get to use rs2? Do I have to create a new connection object even if the connection is to the same DB?
try
{
//Get some stuff
String name = "";
String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
name = rs.getString("name");
}
String sql2 = "SELECT `id` FROM `profiles` WHERE `id` =" + profId + ";";
ResultSet rs2 = statement.executeQuery(sql2);
String updateSql = "INSERT INTO `blah`............";
PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);
while(rs2.next())
{
int id = rs2.getInt("id");
int stuff = getStuff(id);
pst.setInt(1, stuff);
pst.addBatch();
}
pst.executeBatch();
}
catch (Exception e)
{
e.printStackTrace();
}
private int getStuff(int id)
{
try
{
String sql = "SELECT ......;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
return rs.getInt("something");
}
return -1;
}//code continues
The problem is with the way you fetch data in getStuff(). Each time you visit getStuff() you obtain a fresh ResultSet but you don't close it.
This violates the expectation of the Statement class (see here - http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):
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.
What makes things even worse is the rs from the calling code. It is also derived off-of the statement field but it is not closed.
Bottom line: you have several ResultSet pertaining to the same Statement object concurrently opened.
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.
I guess after while(rs2.next()) you are trying to access something from rs1. But it's already closed since you reexecuted statement to get rs2 from it. Since you didn't close it, I beleive it's used again below.

How to assign a Value taken from the database to a label?

I need to assign a string taken by a query from the database to a Jlabel. I tried many methods but failed. How can i do it?
try{
String sql="SELECT MAX(allocationID) FROM allocation where unit='"+ dept + " ' ";
pst=conn.prepareStatement(sql);
String x= (pst.execute());
}
catch(Exception e){
}
Need to study the steps to connect to the database in java First db steps
Get the resultset from the statment by calling ResultSet rs = pst.execute();
Iterate through the list of rows by using the resultset object.
After that assign the value to the JLabel.
You just made several errors in your tiny program, take a look at the code below as an example:
// your way of using prepared statement is wrong.
// use like this
String sql="SELECT MAX(allocationID) FROM allocation where unit=?;";
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
// assign values to the variables in the query string
ps.setString(1, dept);
// execute the query
ResultSet rst = ps.executeQuery();
// parse the result set to get the value
// You'd better do some check here to ensure you get the right result
rst.next();
String x = rst.getInt(1) + "";
ps.close();
conn.close();
}
Have a look at the article if you are interested:https://docs.oracle.com/javase/tutorial/jdbc/basics/retrieving.html

SELECT with WHERE using PreparedStatement

I have this method that selects movie showtimes by movie ID from a MySQL database and puts them in a Time[]. However, it is throwing a syntax exception near '? ORDER BY schedule_id' according to the trace.
public Time[] getShowTimes(int movieId) {
List<Time> list = new ArrayList<Time>();
try {
sql = "SELECT schedule_time FROM schedule WHERE movie_id = ? ORDER BY schedule_id";
ps = conn.prepareStatement(sql);
ps.setInt(1, movieId);
rs = ps.executeQuery(sql);
while(rs.next()) {
list.add(rs.getTime(1));
}
} catch(SQLException se) {
se.printStackTrace();
}
Time[] times = new Time[list.size()];
times = list.toArray(times);
return times;
}
I followed this example (if that helps). What could be wrong?
You are calling the executeQuery(String) method in your PreparedStatement, and that call is just inherited from Statement. But Statement just executes the query without any PreparedStatement placeholder semantics, hence the error.
Instead, you want to call the executeQuery() (no arguments) method. The SQL has already been prepared, and all placeholders have been assigned values, so the SQL argument string is not needed again.
rs = ps.executeQuery();

Categories

Resources