I currently have a result set returned, and in one of the columns the string value may be null (I mean no values at all). I have a condition to implement like following
rs = st.executeQuery(selectSQL);
output = rs.getString("column");
Since the column may be null in the database, the rs.getString() will throw a NullPointerException when the column is null. If column is null, I want the output to be an empty string like output = "";. I can't check if(rs.getString("column) != null either. How can I tackle this situation?
My real problem:
try {
rs = st.executeQuery(sql);
int i = 0;
while (rs.next()) {
output[i] = rs.getString(column);
// column field in the database contains multiple results, but sometimes
// may be null
i++;
}
} catch (SQLException e) {
e.printStackTrace();
// other than tracing the exception i want to fill the array too
}
return output;
Now, if one of the column values contains no value, i.e. null, I want output[i] defined as N/A. This problem stems from the fact that the column field is NULL allowed in the database. And sorry for telling you that it's a NPE, while in fact it's a SQLException.
Since the column may be null in the
database, the rs.getString() will
throw a NullPointerException()
No.
rs.getString will not throw NullPointer if the column is present in the selected result set (SELECT query columns)
For a particular record if value for the 'comumn is null in db, you must do something like this -
String myValue = rs.getString("myColumn");
if (rs.wasNull()) {
myValue = ""; // set it to empty string as you desire.
}
You may want to refer to wasNull() documentation -
From java.sql.ResultSet
boolean wasNull() throws SQLException;
* Reports whether
* the last column read had a value of SQL <code>NULL</code>.
* Note that you must first call one of the getter methods
* on a column to try to read its value and then call
* the method <code>wasNull</code> to see if the value read was
* SQL <code>NULL</code>.
*
* #return <code>true</code> if the last column value read was SQL
* <code>NULL</code> and <code>false</code> otherwise
* #exception SQLException if a database access error occurs or this method is
* called on a closed result set
*/
output = rs.getString("column");// if data is null `output` would be null, so there is no chance of NPE unless `rs` is `null`
if(output == null){// if you fetched null value then initialize output with blank string
output= "";
}
The description of the getString() method says the following:
the column value; if the value is SQL NULL, the value returned is null
That means your problem is not that the String value is null, rather some other
object is, perhaps your ResultSet or maybe you closed the connection or something
like this. Provide the stack trace, that would help.
I was able to do this:
String a;
if(rs.getString("column") != null)
{
a = "Hello world!";
}
else
{
a = "Bye world!";
}
The String being null is a very good chance, but when you see values in your table, yet a null is printed by the ResultSet, it might mean that the connection was closed before the value of ResultSet was used.
Class.forName("org.sqlite.JDBC");
con = DriverManager.getConnection("jdbc:sqlite:My_db.db");
String sql = ("select * from cust where cust_id='" + cus + "'");
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
con.close();
System.out.println(rs.getString(1));
Would print null even if there are values.
Class.forName("org.sqlite.JDBC");
con = DriverManager.getConnection("jdbc:sqlite:My_db.db");
String sql = ("select * from cust where cust_id='" + cus + "'");
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
System.out.println(rs.getString(1));
con.close();
Wouldn't print null if there are values in the table.
The code should be like given below
String selectSQL = "SELECT IFNULL(tbl.column, \"\") AS column FROM MySQL_table AS tbl";
Statement st = ...;
Result set rs = st.executeQuery(selectSQL);
To treat validation when a field is null in the database, you could add the following condition.
String name = (oRs.getString ("name_column"))! = Null? oRs.getString ("name_column"): "";
with this you can validate when a field is null and do not mark an exception.
I came across with the same issue. But I believe , handling null in the sql is not a good option. such things should be handled in java program for better performance.
secondly , rs.getString("column") != NULL is also not a good option as you are comparing string's reference not value. better to use .equals() method while checking null or isEmpty() method. Again, with this you can use null check, that is fine.
You can simply use-
rs = st.executeQuery(selectSQL);
output = rs.getString("column");
if(!output.isEmpty()) {
//
}
In MySQL faced issue with-
output!=null
output!=""
But output.isEmpty() worked for rs.getString().
Related
I am using mySQL. As you see, the SQL statement is wrong at SELECT. So, I wonder what value the rs is?
I hope to get some advice. I thank you so much;
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = stm.executeQuery(sql);
There would be no value because Statement.executeQuery(String) would throw a SQLException. As the linked Javadoc says,
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, the given SQL statement produces anything other than a single ResultSet object, the method is called on a PreparedStatement or CallableStatement
It will return you an exception having message like syntax error.
Easiest way to find is to debug your code by putting break points in code & examining / watching values of variables . Most IDEs have these debugging features. In addition to Elliott Frisch's answer, if I restructure your code like below then in case of invalid / incorrect SQL, control comes to catch block and you can see that value of rs remains null.
public void executeQuery(Connection conn, String username,String password) {
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = null;
Statement stm = null;
try {
stm = conn.createStatement();
rs= stm.executeQuery(sql);
while(rs.next()) {
//Extract ResultSet here as per needed logic
}
} catch (SQLException e) {
// Your control comes here if query is wrong , put a break point at below line & examine value of rs
e.printStackTrace();
}finally {
// Close resources not needed after this method call like - result sets , statements & connection
}
}
Firstly statement won't execute, so next execution is depends on how you are going to handle that exception. So, if exception comes and if you handle also there will be null in ResultSet because no value assigned to it.
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.
I am trying to check if a player is already is in the database with this code:
Statement sql = mySql.getConnection().createStatement();
ResultSet check = sql.executeQuery("SELECT * FROM `playerinfo` WHERE Username='" + player.getName() + "';");
System.out.println(check.toString());
if(check != null) {
System.out.println("2");
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Player already in database");
check.close();
sql.close();
return;
}
I checked but nothing is in the database and it says that the player already contains in the database
Sorry for bad english
Some considerations:
When checking whether the database contains a certain value, it's good practise to do this using a query that returns a single value (and not SELECT * which returns all columns of all rows that match the WHERE condition). You can do this e.g. by selecting a single check flag (SELECT 1) with a row-limiting clause (LIMIT 1):
SELECT 1 FROM playerinfo WHERE Username = ? LIMIT 1
This query is guaranteed to return only one row (with a single column, '1') if a player with the given name exists, or no rows if there are no players with the given name.
As others have pointed out, when you're inputting parameters into the query, you should use a PreparedStatement instead of a simple statement with concatenated inputs. This way, you can avoid SQL injection and the database is also able to reuse/cache the query (or cursor) internally.
Finally, you should close the resources you use, even if an Exception gets thrown during the execution. This is best done in the finally clause, or if you're on Java 7 or later, using the try-with-resources statement.
With these things in mind, a re-write of your code could look like this:
PreparedStatement ps = null;
try {
ps = mySQL.getConnection()
.prepareStatement("SELECT 1 FROM playerinfo WHERE Username = ? LIMIT 1");
ps.setString(1, player.getName());
ResultSet rs = ps.executeQuery();
// the first invocation of rs.next() returns true if
// there are rows in the result set, or false if no rows were found
if (rs.next()) {
System.out.println("2");
Bukkit.getConsoleSender().sendMessage(ChatColor.RED
+ "Player already in database");
}
rs.close();
} finally {
if (ps != null) {
ps.close();
}
}
I think instead of checking if the ResultSet is null or not, you should check if the ResultSet contains any row or not.
Apart from that, use PreparedStatements.
ResultSet zoeken = stat.executeQuery("SELECT * FROM leden WHERE naam = '" + text + "'");
if (zoeken.getRow() == 0){
System.out.println("hi");
}
while( zoeken.next() ){
System.out.println(zoeken.getString(1) + zoeken.getString(2) + zoeken.getString(3));
}
I am using this to check if the result zoeken is empty, but it throws an exception saying its illegal to do that regardless if it works or not.
What is a better solution to check if result is empty or not
// I am using this to check if the result"zoeken" is empty, but it
throws an exception saying its illegal to do that. regardless if it
works or not
Don't invoke ResultSet.getRow() before you invoke ResultSet.next().
From API:
A ResultSet object maintains a cursor pointing to its current row of
data. Initially the cursor is positioned before the first row. The
next method moves the cursor to the next row, and because it returns
false when there are no more rows in the ResultSet object, it can be
used in a while loop to iterate through the result set.
ResultSet zoeken = stat.executeQuery("SELECT * FROM leden WHERE naam = '" + text + "'");
boolean val = zoeken.next(); //next() returns false if there are no-rows retrieved
if(val==false){
System.out.println("zoken is empty"); //prints this message if your resultset is empty
}
while(val){// only runs when there are rows in the resultset
System.out.println(zoeken.getString(1) + zoeken.getString(2) + zoeken.getString(3));
val=zoeken.next(); //updating val again to check if there are rows in result set
}
If your result set is empty zoeken.next() will return false in which case your while loop will not execute.
An Advice
use PreparedStatement Instead of simple Statement. simple statement would lead to SQL Injection and also would ease the pain for writing complex queries.Below is the sample code which use PreparedStatement.
String yourquery ="Select whatever From table where col1= ? and col2 =?"
PreparedStatement stmnt = Conn.preparedStatement(yourquery);
stmnt.setString(1, "val1");
stmnt.setString(2, "val2");
Use next() method
boolean hasNext = zoeken.next();
Following code will work for you
if(!zoeken.first() && !zoeken.next())//if fist and next records are empty
{
System.out.println("Result set is empty");
}
else
{
System.out.println("Result set is not empty");
}
According to next() you must first use next and then getRow()
ResultSet zoeken = stat.executeQuery("SELECT * FROM leden WHERE naam = '" + text + "'");
while( zoeken.next() ){
int rowNum = zoeken.getRow();
System.out.println(zoeken.getString(1) + zoeken.getString(2) + zoeken.getString(3));
}
without using Result Set next() you cant check the size or resultSet period.
A ResultSet cursor is initially positioned before the first row.
I know the OP probably doesn't need the info any more but if someone stumbles across this, I would agree with everything #PermGenError has said although, I feel a more elegant solution for the given code but using prepared statements would be:
PreparedStatement ps = conn.prepareStatement("SELECT * FROM leden WHERE naam = ?");
ps.setString(title);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
do {
System.out.println(zoeken.getString(1) + zoeken.getString(2) + zoeken.getString(3));
} while (rs.next());
} else {
System.out.println("hi");
}
I have written this freehand so excuse any mistakes or if it doesn't compile. I just feel this is clearer and cuts down on the usage of local variables. If there is at least one row, go print the row and keep doing this until there are no more rows otherwise say "hi". But I assume you would want to say something more useful than "hi" maybe a "No results found" message or something.
I inserted one column in sql with null value from java.while retrieving back it is not working with null.i also checked with string.length().But when i printed the value in System.out. the value is showing as null (just null).when i checked it with condition it is not entering into loop.
String id ="1234";
String name="pratap";
String gender=null;
String email=null;
String service="GOOGLE";
log.info(id+name+gender+email) //output is 1234pratapnullnull
String insert = "INSERT INTO oauthuser VALUES('"+id+"','"+name+"','"+gender+"','"+email+"','"+service"')";
In the retrieval
query ="Select * FROM oauthuser where id="+"'"+id+"'";
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection (dbUrl);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
while(rs.next())
{
id=rs.getString(1);
name=rs.getString(2);
gender=rs.getString(3);
email=rs.getString(4);
service_provider_name=rs.getString(5);
System.out.println(gender+email+name);//output is nullnullpratap
}
if(gender!="male" && gender!="female")
System.out.println("it is printing");
if(gender==null)
System.out.println("it is not printing");
con.close();
From your somewhat cryptic description of the problem I suspect that you may have inserted the string "null" rather than the SQL NULL value. The two are not the same (very different, in fact).
edit Having reviewed the code, this is exactly what happens. Take, for example, gender:
String gender = null;
...'"+gender+"',...
The above converts it to 'null' (i.e. the SQL string "null"), and inserts that into the database.
My basic advice would be to read up on PreparedStatement and use that instead of building the SQL query bit by bit as you're doing right now.
Finally, the following is broken:
if(gender!="male" && gender!="female")
This should be
if(!gender.equals("male") && !gender.equals("female"))
you can try "null" instead of NULL , but better to show us the code
after your update
remove + sign from your query like this
String id ="1234";
String name="pratap";
String gender="null";
String email="null";
String service="GOOGLE";
log.info(id+name+gender+email) //output is 1234pratapnullnull
String insert = "INSERT INTO oauthuser VALUES('"id"','"name"','"gender"','"email"','"service"')"
and when you select , modify like this
if(gender.equals("null"))
System.out.println("it is not printing");
Maybe your value is not null but "null" string? Start your application in debug, put break point and check it.