I know it may seem like an easy to solve problem, but I can't find my fault in this piece of code. I'm returning int and Eclipse is telling me that 'This method must return a result of type int'.
public static int getLastId(int table) {
Connection connection = null;
String url = "jdbc:postgresql://someServer:port/someDB";
try {
//Verbindung herstellen
connection = DriverManager.getConnection(url, "someUser",
"somePassword");
} catch (SQLException e1) {
//fehlerhafte Verbindung
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
//0 - source ; 1 - destination Table
if(table == 0){
Statement stmt = connection.createStatement();
ResultSet lastId;
lastId = stmt.executeQuery("SELECT index FROM table0 ORDER BY someIndex DESC LIMIT 1");
String theLastId0 = "";
while(lastId.next())
{
//System.out.print(lastId.getString("index"));
theLastId0 = lastId.getString("index");
}
lastId.close();
stmt.close();
connection.close();
int letzteId0 = Integer.parseInt(theLastId0);
return letzteId0;
}else if(table == 1){
Statement stmt = connection.createStatement();
ResultSet lastId;
lastId = stmt.executeQuery("SELECT index FROM table1 ORDER BY someIndexDESC LIMIT 1");
String theLastId1 = "";
while(lastId.next())
{
//System.out.print(lastId.getString("index"));
theLastId1 = lastId.getString("index");
}
lastId.close();
stmt.close();
connection.close();
int letzteId1 = Integer.parseInt(theLastId1);
return letzteId1;
}
}
catch (SQLException e) {
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
return -1;
}
}
What happens if table != 0 and table != 1? Then your method doesn't return anything. So either add an else statement to your if or just a regular return, returning a dummy value like -1.
Even if you, the programmer, know that this case will never be executed, the compiler doesn't know that so you gotta make it happy anyways. Plus nasty things can be done using reflection so it's never a good idea to assume the input to your methods are valid.
This method must Always return an int.
You must add the following else statement
else {
return 0;
}
after the else if because in your version you don't return anything if your if AND your else if evaluates to false.
If table != 0 or 1, then your code does not return anything. Just add return 0; at the very end or whatever the appropriate behavior is, then you should be fine.
For future reference, your methods must return a value in every condition if a return type is specified. If there is a situation where nothing is returned, then the code is faulty. Hope it helps!
Related
I was wondering how to issue a MySQL command that checks if a table within my database is empty and then subsequently store the boolean result into a java variable. I am trying to use JDBC commands to do this.
This is what I have so far but it is not working properly:
#Override
public boolean isEmpty(Connection connection) {
Statement statement = null;
ResultSet resultSet = null;
Boolean var = true;
try {
statement = connection.createStatement();
System.out.println(statement.execute("SELECT EXISTS (SELECT 1 FROM Persons) AS OUTPUT"));
if(statement.execute("SELECT EXISTS (SELECT 1 FROM Persons)")) {
var = false;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return var;
}
When I run the program with a completely new, unpopulated mySQL table, the function returns true. Does anyone know a solution?
Your test checks if the table exists, instead you want to see if the table contains any rows. In order to do so, select the count of rows from the table and verify it is greater than 0. Prefer PreparedStatement over Statement (it's more efficient and performant), and you need a ResultSet to actually iterate the result from the server. Something like,
#Override
public boolean isEmpty(Connection connection) {
PreparedStatement statement = null;
ResultSet resultSet = null;
boolean res = false; // no need for the wrapper type here.
String sql = "SELECT COUNT(*) FROM Persons";
try {
statement = connection.prepareStatement(sql);
System.out.println(sql);
resultSet = statement.executeQuery();
if (resultSet.next()) {
res = resultSet.getInt(1) > 0;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return res;
}
Changed var to res because (as of Java 10) var is now a keyword in Java.
As you are executing a select statement, instead of using Statement.execute(..), you should use Statement.executeQuery(..) and iterate over its result set.
The boolean return value from execute(..) indicates if the first value is a result set or not. It is not the boolean column from your query. You should normally only use execute(..) if you don't know what type of statement it is, or if it is a statement that can produce multiple results (update counts and result sets).
So, instead use:
boolean exists;
try (ResultSet rs = statement.executeQuery("SELECT EXISTS (SELECT 1 FROM Persons)")) {
exists = rs.next() && rs.getBoolean(1);
}
I'm using SQL to compare a date of an event
public static boolean sameDate(String DateString)
{
PreparedStatement statement = Application.database.newStatement("SELECT * FROM BookShift WHERE id = ? IN (SELECT id FROM Class WHERE Date = ?)");
try
{
if(statement !=null)
{
statement.setInt(1, main.id);
statement.setString(2, DateTwo);
ResultSet results = Application.database.runQuery(statement);
if (results != null)
{
return true;
}
else {
return false;
}
}
}
catch (SQLException resultsexception)
{
System.out.println("Database result processing error: " + resultsexception.getMessage());
}
return false;
}
Whenever I run my program and try booking a new shift, regardless of whether it does clash or not it always returns that it does.
You need to check if the result set has any rows or not, not check if it is null.
if (results.next())
{
return true;
}
else {
return false;
}
or, of course, just
return results.next();
As the comments say, it is not generally correct to check if results is null. I don't have the SQL experience to tell you what runQuery() will return on a query that fails, but I doubt that it's null, I would expect it to return an empty ResultSet.
Checking if it's null first isn't a bad thing, and in fact is a good idea to avoid NullPointerException throws. However, it's not enough to just use that check.
I am writing a generic Java code and i want to add integers to a min Heap which will be stored in a mysql database. For that i have written below code,
public void addElement(Comparable value) {
sql = "INSERT INTO testHeap VALUES("+size+","+(int)value+ ") ";
try {
stmt.executeUpdate(sql);
size++;
} catch (SQLException ex) {
Logger.getLogger(HeapMySql.class.getName()).log(Level.SEVERE, null, ex);
}
if(size == 0) throw new IllegalStateException("Shape error");
int index = size - 1;
while(size != 0) {
sql = "SELECT value FROM testHeap WHERE indexnum ="+index;
T val;
try {
val = (T)stmt.executeQuery(sql);
if(myParent(index).compareTo(val) <= 0) break;
swap(parent(index), index);
index = parent(index);
} catch (SQLException ex) {
Logger.getLogger(HeapMySql.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This returns below exception in runtime
Exception in thread "main" java.lang.ClassCastException: com.mysql.jdbc.JDBC4ResultSet cannot be cast to java.lang.Comparable
at Lab03.HeapMySql.addElement(HeapMySql.java:140)
I wan to know how to do this "val = (T)stmt.executeQuery(sql)" properly :)
You need to specify a column in the result set (even though there's only one)
val = (T)new Integer(stmt.executeQuery(sql).getInt(1));
As you commented below, you need an active row in your result set.
You also need to close it after you're done or you'll run out of database cursors. Reading past the last row (using rs.next) will automatically close it, so I use a "while" instead of an "if".
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
val = (T)new Integer(rs.getInt(1)))
}
The ResultSet has all results as an Object in an array, it's not the result itself! You have to cast every single one to the type it is. Furthermore the ResultSet can be used to make easy changes back to the database, too. So you didn't get the concept of jdbc at all ^^ You should read a few tutorials how to work with jdbc in general.
For further help please make your question better understandable. We can't know which line is 140 (from the error), i assume:
if(myParent(index).compareTo(val) <= 0) break;
I am moving from PHP to Java and I'm a little struggled.
I have this method like this that I use to get some data from MySQL database and I would like to treat the failure if no data got from database.
public double getRate() {
double ret;
try {
// do a select query
PreparedStatement stmt = conn.prepareStatement("SELECT `rate` FROM `rates` LIMIT 1");
ResultSet rs = stmt.executeQuery();
// get result
rs.absolute(1);
ret = rs.getDouble(1);
// close the resources
rs.close();
stmt.close();
}
// this catches only the SQL errors (if I am right)
catch (SQLException ex) {
ex.printStackTrace();
}
// THIS IS WRONG BECAUSE "variable ret might not have been initialized"
return ret;
}
In PHP we can return whatever in case of failure like this:
<?php
public function getRate() {
$ret = db::getOne("SELECT `rate` FROM `rates` LIMIT 1");
if ($ret) {
return $ret; // row has been found, so we return it
} else {
return false; // row hasn't been found, so we return false --> THIS is what I need to do in Java
}
}
?>
So how to treat a failure in Java methods/functions where I have nothing to return?
You have several options:
throw an exception, and catch this by the code which calls the method. This works well, is a nice way to handle it. But requires a lot of additional try-catch statements
Return -1 on error. This is also a very common way to do if you work with natural numbers only
always return a result object, which contains a the output and a success/error status
Use the Double Class instead, and return null on fail
In Java, you can't return double from one place and boolean from another. What you could do is, initialize your Double (wrapper of double primitive) value like:
Double ret = null;
And if there are no rows or any SQLException, you would return this value back to caller. In called method you could do something like:
Double rate = getRate();
if (rate == null) {
//no row found
} else {
//i have the row. continue with business logic
}
You could make your method return an object of the double wrapper class Double. Then you could return a null pointer in case of some failure.
public Double getRate() {
...
if(ok)
return new Double(ret);
else
return null;
}
Initialize your double variable with a control value. If it is not changed when exiting the method, then something went wrong.
The control value can be something you do not expect to get from the query, so for rates it could be a negative number, say -1 since rates can't be negative.
double ret=-1.00d;
I am adding a sample code so you can understand how to handle such scenarios.
If your default value does not changes,it means there was nothing that matched your query.
public double methodName(int arg)
{
double risk=0.0;
String query = null;
PreparedStatement stm = null;
ResultSet r = null;
Connection con=null;
try{
con=ConnectionDB.getConnection();
if(con!=null)
{
query="select risk from table where year="+arg;
stm = con.prepareStatement(query);
r = stm.executeQuery();
if(r.next())
{
risk=r.getDouble(1);
}
}
}catch(Exception e)
{
e.printStackTrace();
}
finally{
try {
if (r != null) {
r.close();
}
if (stm != null) {
stm.close();
}
if(con!=null)
{
con.close();
}
} catch (Exception e) {
System.out.println("" + e);
}
}
return risk;
}
You could return an OptionalDouble, which makes it obvious to the caller that they need to handle the case of the result not being found:
try {
// get ret
return OptionalDouble.of(ret);
} catch (SQLException ex) {
return OptionalDouble.empty();
}
In your Java example, when you talk about a "failure", you are talking about an unexpected error (e.g. a SQL Exception, a non-expected error in the DB access).
Nevertheless, in your PHP example, when you talk about a "failure", you are talking about a normal scenario (No data in database).
So, both examples are quite different.
In my opinion, if I get an unexpected sitution, I wouldn't return any value, I'd throw an exception. I usually return null, -1 and this kind of values in normal and expected scenarios where there isn't data to return.
Class.forName("org.sqlite.JDBC");
Connection conn =
DriverManager.getConnection("jdbc:sqlite:userdata.db");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT * from table WHERE is_query_processed = 0;");
int rowcount = rs.getRow();
System.out.println("Row count = "+rowcount); // output 1
rs.first(); // This statement generates an exception
Why is it so?
The pattern I normally use is as follows:
boolean empty = true;
while( rs.next() ) {
// ResultSet processing here
empty = false;
}
if( empty ) {
// Empty result set
}
Here's a simple method to do it:
public static boolean isResultSetEmpty(ResultSet resultSet) {
return !resultSet.first();
}
Caveats
This moves the cursor to the beginning. But if you just want to test whether it's empty, you probably haven't done anything with it yet anyways.
Alternatively
Use the first() method immediately, before doing any processing.
ResultSet rs = stat.executeQuery("SELECT * from table WHERE is_query_processed = 0;");
if(rs.first()) {
// there's stuff to do
} else {
// rs was empty
}
References
ResultSet (Java Platform SE 6)
You can do this too:
rs.last();
int numberOfRows = rs.getRow();
if(numberOfRows) {
rs.beforeFirst();
while(rs.next()) {
...
}
}
while (results.next())
is used to iterate over a result set.so results.next() will return false if its empty.
Why is execution not entering the
while loop?
If your ResultSet is empty the rs.next() method returns false and the body of the while loop isn't entered regardless to the rownumber (not count) rs.getRow() returns. Colins example works.
Shifting the cursor forth and back to determine the amount of rows is not the normal JDBC practice. The normal JDBC practice is to map the ResultSet to a List of value objects each representing a table row entity and then just use the List methods to determine if there are any rows.
For example:
List<User> users = userDAO.list();
if (users.isEmpty()) {
// It is empty!
if (users.size() == 1) {
// It has only one row!
} else {
// It has more than one row!
}
where the list() method look like as follows:
public List<User> list() throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<User> users = new ArrayList<User>();
try {
connection = database.getConnection();
statement = connection.createStatement();
resultSet = statement.executeQuery(SQL_LIST);
while (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong("id"));
user.setName(resultSet.getString("name"));
// ...
users.add(user);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
return users;
}
Also see this answer for other JDBC examples.
CLOSE_CURSORS_AT_COMMIT
public static final int CLOSE_CURSORS_AT_COMMIT
The constant indicating that ResultSet objects should be closed when the method Connection.commit is called.
Try with this:
ResultSet MyResult = null;
MyResult = Conexion.createStatement().executeQuery("Your Query Here!!!");
MyResult.last();
int NumResut = MyResult.getRow();MyResult.beforeFirst();
//Follow with your other operations....
This manner you'll be able work normally.
This checks if it's empty or not while not skipping the first record
if (rs.first()) {
do {
// ResultSet is not empty, Iterate over it
} while (rs.next());
} else {
// ResultSet is empty
}
May be you can convert your resultset object into String object and check whether is it empty or not.
`if(resultset.toString().isEmpty()){
// containg null result
}
else{
//This conains the result you want
}`