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.
Related
I´m new to SQL. My goal is, to create a program, which should check whether a certain table has a certain value. I´ve wrote this method
public boolean existString(final String query) {
try {
final Statement statement = this.conn.createStatement();
result = statement.executeQuery(query);
return true;
} catch(SQLException e) {
e.printStackTrace();
return false;
}
}
As you can see, its a method for executing a SQL-statement. I think this may be the right statement :
String query = "select * from table where column1 = 'checkvalue'"; // of course i need to replace table and column and checkvalue
But atfer executing this statement, how can I prove if it was successfull (Does the query return something)? If the statement, after executing would return something, I could easly use a if-statement to check.
A SQL statement can return successfully if there are no rows returned from the database, so using a SQLException is not going to help you if the query is correct but there is no match.
public boolean existString(final String query) {
try {
final Statement statement = this.conn.createStatement();
result = statement.executeQuery(query);
return result.next();
} catch(SQLException e) {
e.printStackTrace();
return false;
}
}
You should leverage the fact that result.next() attempts to move the result pointer to the next row and return whether or not there is a row to return. This way, if successful and there is results ir returns true and of successful and not results, it returnsfalse. If something goes wrong, you're exception handling will take care of hte rest.
Yes, your method and SQL query are enough for checking. If there is no row output in the query, it will be null.
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.
I am attempting at writing my own server as a personal project, however I'm running into some issues. I've finally completed the setup for a packet system between the Java server and the C# client which makes me very happy, even though I've had some help. Anyway, here's the code that I've written trying to get this to work properly. I created the SQLManager using static variables, because I read that the database connection should be static, if this is incorrect, please let me know.
Here's the error:
Exception in thread "main" java.lang.NullPointerException
com.fmeg.server.util.SQLManager.runQuery(SQLManager.java:37)
Here's my SQL Class:
public static boolean connectToDatabase() {
try {
connection = DriverManager.getConnection(host, credentials[0], credentials[1]);
connected = true;
} catch (Exception e) { connected = false; }
Misc.log("Database: " + database + " || Connection State: " + connected);
return connected;
}
public static boolean runQuery(String query) {
try {
ResultSet rs = checkQuery(query);
if(rs == null)
Misc.error("Result Set returned null.");
if(rs.next())
Misc.log("Current Row: " + rs.getRow());
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static ResultSet checkQuery(String query) throws SQLException {
try {
Misc.log(query);
return statement.executeQuery(query);
} catch (Exception e) {
destroyConnection();
return null;
}
}
private static void destroyConnection() {
try {
statement.close();
connection.close();
connected = false;
Misc.error("Database connection destroyed!");
} catch (Exception e ) { }
}
Apparently, the ResultSet is returning null, here's the output in the console.
[LOG]: Database: Unity3D || Connection State: true
[LOG]: Server <Test Realm> Successfully Started on port: 9955!
[LOG]: select * from `accounts`
[ERROR]: Result Set returned null.
Here's where I'm calling the query:
SQLManager.runQuery("select * from \'accounts\'");
Any pointers would be greatly appreciated, as I don't exactly see what the problem is. To answer these questions if the do arise, yes I do have a table called accounts, and yes it does have entries.
You have a syntax error on table name. Table names should not be a literal but should be quoted with back ticks. These back ticks are optional unless table name has any special chars in it or if it is a reserved word.
Just because of this error, the statement
return statement.executeQuery(query);
is causing an Exception and the method was returning a null for ResultSet.
You better catch the exception and see what the stacktrace says on it.
Change:
QLManager.runQuery("select * from \'accounts\'");
To:
QLManager.runQuery("select * from `accounts`");
You problem in this code:
if(rs == null) {
Misc.error("Result Set returned null.");
if(rs.next())
Misc.log("Current Row: " + rs.getRow());
In case any exception occurred in checkQuery method, it will return a null for ResultSet, then the code will proceed to rs.next(), which rs null, then a NullPointerException will raise.
What all you have to do is:
if(rs == null) {
Misc.error("Result Set returned null.");
return false;
}
if(rs.next()) {
Misc.log("Current Row: " + rs.getRow());
return true;
}
But you have to at least to log the error or throw the exception in checkQuery to figure out what is the exact problem that you are facing. not just return null object.
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!
public ResultObject takePrefixGroupId(ArrayList prefixGroupName)
{
debugLog(MODULE_NAME, "Inside the takePrefixGroupId() of LCRConfigurationSessionBean");
ResultObject resultObject = new ResultObject(LCRResponseCode.LCR_CONFIGURE_SEARCH_ERROR_EJB, null);
String strSelectQuery = null;
String strMessage=null;
ResultSet resSet = null;
Collection colInValideRecord =new ArrayList();
Collection colErrorMessage=new ArrayList();
Collection colValidRecord = new ArrayList();
Collection colDataValidation=null;
try{
for(int i=0;i<prefixGroupName.size();i++)
{
strSelectQuery = "select DESTINATIONGROUPID from TBLMDESTINATIONGROUP where NAME='"+prefixGroupName.get(i)+"'";
debugLog(MODULE_NAME, "Query::::::"+strSelectQuery);
resultObject = execute(strSelectQuery);
if(resultObject.getResponseCode() == LCRResponseCode.SUCCESS_RESPONSE_CODE)
{
resSet = (ResultSet)resultObject.getResponseObject();
debugLog(MODULE_NAME, "resSet::::::"+resSet);
if(resSet != null)
{
while(resSet.next())
{
colValidRecord.add(resSet.getString("DESTINATIONGROUPID"));
}
}
else
{
strMessage=LCRResponseCode.errorCodeToMessage(LCRResponseCode.PREFIX_GROUP_DOES_NOT_EXIST_ERROR);
debugLog(MODULE_NAME,"MESSAGE::: "+strMessage);
colErrorMessage.add(strMessage);
colInValideRecord.add(prefixGroupName);
debugLog(MODULE_NAME,"No Prefix Group is found.");
}
colDataValidation=new ArrayList();
colDataValidation.add(colValidRecord);
colDataValidation.add(colInValideRecord);
colDataValidation.add(colErrorMessage);
resultObject.setResponseObject(colDataValidation);
resultObject.setResponseCode(LCRResponseCode.SUCCESS_RESPONSE_CODE);
}
else
{
debugLog(MODULE_NAME, "Unable to execute search query for in searchDestination() of LCRConfigurationSessionBean.");
resultObject.setResponseCode(LCRResponseCode.LCR_CONFIGURE_SEARCH_ERROR_EJB);
}
}
}
catch(Exception e)
{
e.printStackTrace();
errorLog(MODULE_NAME, "exception in searchDestination() of LCRConfigurationSessionBean");
resultObject.setResponseCode(LCRResponseCode.LCR_CONFIGURE_SEARCH_ERROR_EJB);
resultObject.setException(e);
}
return resultObject;
}
this is the code
According to the javadoc, Statement.executeQuery() never returns null. So the answer is a ResultSet with no rows.
You can tell that the ResultSet is empty if next() returns false the first time you call it.
You may also be able to tell by calling the optional isAfterLast() method. If it is supported, this method will give you an answer without advancing the cursor as a side-effect.
I've no idea what the answer would be for your code, since you are calling an execute method whose implementation you have not provided.
ResultSet executeQuery(String sql)
throws SQLException Executes the given SQL
statement, which returns a single
ResultSet object.
Parameters: sql - an SQL statement to be sent to the database, typically
a static SQL SELECT statement
Returns: a ResultSet object that contains the data produced by the
given query; never null
Throws: SQLException - if a database access error occurs, this
method is called on a closed Statement
or the given SQL statement produces
anything other than a single ResultSet
object
Statement
Also you can do it like:
if(resSet.last().getRow() > 0)
{
resSet.first();
while(resSet.next())
{
colValidRecord.add(resSet.getString("DESTINATIONGROUPID"));
}
}
else
{
//...