java.lang.NullPointerException - ResultSet - java

I am getting the following error:
java.lang.NullPointerException
at oracle.jdbc.driver.ScrollableResultSet.cacheRowAt(ScrollableResultSet.java:2086)
at oracle.jdbc.driver.ScrollableResultSet.isValidRow(ScrollableResultSet.java:2060)
at oracle.jdbc.driver.ScrollableResultSet.next(ScrollableResultSet.java:347)
at website.web.InboxReader.getkeywordImportance(InboxReader.java:832)
at website.web.InboxReader.main(InboxReader.java:54)
There are 53 rows in Mail table and 1 row in keyword table. On debugging, as soon as the line is executed kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE = IMPORTANCE + 1.0 WHERE SKEYWORD = '" + s2 + "'"); it goes again to keyword set.next() and throws the exception.
Here is the code:
Connection connection = connectToDatabase();
Statement mstmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
String s1,s2;
ResultSet mailset = mstmt.executeQuery("SELECT * from MAIL");
System.out.println("hello in getImportance beg");
//mailset.beforeFirst();
while(mailset.next())
{
System.out.println("hello in first while");
Statement kstmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet keywordset = kstmt.executeQuery("SELECT * FROM KEYWORD");
while(keywordset.next())
{
s1=mailset.getString("SUBJECT");
System.out.println("Subject: "+s1);
s2=keywordset.getString("SKEYWORD");
System.out.println("Keyword: "+s2);
if(s1.contains(s2))
{
System.out.println("hello in if");
kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE = IMPORTANCE + 1.0 WHERE SKEYWORD = '" + s2 + "'");
}
}
keywordset.close();
}
mailset.close();
connection.close();
Thanks!

if you take a look at this line which seems to be problematic:
kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE ='" + (keywordset.getFloat("IMPORTANCE") + 1.0) + "'");
You should double check the call
keywordset.getFloat("IMPORTANCE")
This mostlikely due to the fact the the column Importance is empty for the record or that the column might not exist. Just to debug you try with
keywordset.getFloat(0);
or which ever id of a column you know exist to see if the call works.
Have you tried removing the COMMIT statement ? Because usually unless you specify otherwise the data is automatically committed so there is no need to call a commit after your statement and if you have specified the auto_commit to false then to commit you should do con.commit() and not call it through an update statement

Please see the documentation here
http://download.oracle.com/javase/tutorial/jdbc/basics/retrieving.html
No need to call beforeFirst as you seem to expect next to behave.
public static void viewTable(Connection con) throws SQLException {
Statement stmt = null;
String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from " + dbName + ".COFFEES";
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
int supplierID = rs.getInt("SUP_ID");
float price = rs.getFloat("PRICE");
int sales = rs.getInt("SALES");
int total = rs.getInt("TOTAL");
System.out.println(coffeeName + "\t" + supplierID + "\t" + price + "\t" + sales + "\t" + total);
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
}

Have you tried running it without keywordset.beforeFirst() and mailset.beforeFirst() ? That is not required, and it might be creating an issue in ResultSet.

kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE = IMPORTANCE + 1.0 WHERE SKEYWORD = '" + s2 + "'");
When this line execute in your code your keywordset ResultSet object will change because all execute methods will cause effect on ResultSet.
All execution methods in the Statement interface implicitly close a statment's current ResultSet object if an open one exists.
What you have to do is create a separate object of statement for running this query so that keywordset ResultSet won't get affected ... ...:)

Related

ORA-00923: FROM keyword not found where expected in SeleniumWebDriver

I created a class (ValidarStatusOsPage) in java that makes a connection to the DB and returns to a test class (ValidateStatusOsTest) the result of the query and prints to the screen.
When I run the test class, the Eclipse console displays the message:
ORA-00923: FROM keyword not found where expecte
I have reviewed the code several times but I can not verify where the error is.
Below is the Java class for connecting to the DB and the test class.
public class ValidarStatusOsTest {
static String query;
#Test
public void validarOs() {
ValidarStatusOsPage os = new ValidarStatusOsPage();
query = os.returnDb("179195454");
}}
public class ValidarStatusOsPage {
String resultado;
public String returnDb(String NuOs) {
// Connection URL Syntax: "jdbc:mysql://ipaddress:portnumber/db_name"
String dbUrl = "jdbc:oracle:thin:#10.5.12.116:1521:desenv01";
// Database Username
String username = "bkofficeadm";
// Database Password
String password = "bkofficeadmdesenv01";
// Query to Execute
String query = "SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURA" +
"FROM tb_bkoffice_os"+
"WHERE NU_OS ="+ NuOs +"";
try {
// Load mysql jdbc driver
Class.forName("oracle.jdbc.driver.OracleDriver");
// Create Connection to DB
Connection con = DriverManager.getConnection(dbUrl, username, password);
// Create Statement Object
Statement stmt = con.createStatement();
// Execute the SQL Query. Store results in ResultSet
ResultSet rs = stmt.executeQuery(query);
// While Loop to iterate through all data and print results
while (rs.next()) {
String NU_OS = rs.getString(1);
String CD_ESTRATEGIA = rs.getString(2);
String CD_STATUS = rs.getString(3);
String NU_MATR = rs.getString(4);
String DT_ABERTURA = rs.getString(5);
resultado = NU_OS + " " + CD_ESTRATEGIA + " " + CD_STATUS + " " + NU_MATR + " " + DT_ABERTURA + "\n";
System.out.println(NU_OS + " - " + CD_ESTRATEGIA + " - " + CD_STATUS + " - " + NU_MATR + " - "+ DT_ABERTURA);
}
// closing DB Connection
con.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return resultado;
}}
3 points are there in your query:
SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURA" +
"FROM tb_bkoffice_os"+
"WHERE NU_OS ="+ NuOs +""
space before FROM missed first part of query is: SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURAFROM
space missed before WHERE: SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURAFROM tb_bkoffice_osWHERE NU_OS =
concatenate parameter into SQL string is exact hack point for SQL Injection attack. Never do it in real program even if it is pure standalone. Always use parameters for queries.
and a little last one: + NuOs +"" - last "" has no sense at all...
good luck.
UPD: #YCF_L absolutely right use Prepared statement.
you need to do this:
in Sql String: WHERE NU_OS = ?
in code:
PreparedStatement stmt = con.prepareStatement(query);
stmt.setString(1, NuOs);
//also works: stmt.setObject(1,NuOs);
things to remember with JDBC:
all parameters in SQL are just ? marks
parameter indexes start with 1 (not 0)
and in order they appear in SQL from strat to end
(e.g. Select * FROM tbl WHERE col1=? and col2=?
has parameter 1 for col1 and parameter 2 for col2
PS. your initial SQL has one more error but I'm not going to tell you what is it :-) use parameter and all be fine.

Resultset.next returns true but doesn't return the value

I am trying to read from a mysql table and I am doing the following:
protected void pushRegisteredStudentsData() {
try {
conn = (Connection) DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
String userID = "SELECT * FROM STUDENT";
rs = stmt.executeQuery(userID);
while (rs.next()) {
int id = rs.getInt("ID");
this.studentID = id;
String insertSql = "INSERT INTO REGISTEREDSTUDENTS(StudentID, ModuleCode) VALUES ('" + studentID + "', + '"
+ this.moduleCode + "')";
System.out.println("Inserting into REGISTEREDSTUDENTS.. [" + id + "]" + "[" + this.moduleCode + "]");
stmt.executeUpdate(insertSql);
}
} catch (SQLException e) {
}
}
..but for some reason,
while (rs.next()) {
int id = rs.getInt("ID");
always returns the same ID, even though the table has different ID's on every line!
Does anyone have an idea why that might be?
Thank you in advance! :(
EDIT:
I was using a single statement to execute 2 updates, which was causing the problem!
It is a bit weird that it returns always the same value because it should only return the first value ONCE.
If you print the stacktrace instead of just catching the exception and doing nothing, you will see that it will print something like:
java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:794)
You are using THE SAME statement for a Select and then for an Insert. This causes the resultSet that is "attached" to the Statement to close because it is not supposed to be used again.
It can be easily fixed by creating another statement:
String insertSql = "INSERT INTO REGISTEREDSTUDENTS(StudentID, ModuleCode) VALUES ('" + studentID + "', + '"
+ this.moduleCode + "')";
System.out.println("Inserting into REGISTEREDSTUDENTS.. [" + id + "]" + "[" + this.moduleCode + "]");
Statement stmt2 = conn.createStatement();
stmt2.executeUpdate(insertSql);

LIKE Statements Not Working in Java SQL Prepared Statement

I'm working on creating a Java interface for an SQL database. I'm using prepared statements to perform the search queries, however they only work with "=" statements and not with LIKE statements.
The first sample code using "=" works successfully. The second sample, using a LIKE statement, does not work and just returns empty.
WORKS:
PreparedStatement SearchQuery = con.prepareStatement("Select * From Alumnus_A Where aFirstName = ? ORDER BY aLastName asc");
SearchQuery.setObject(1, FirstName);
ResultSet rs=SearchQuery.executeQuery();
DOESN'T WORK:
PreparedStatement SearchQuery = con.prepareStatement("Select * From Alumnus_A Where aFirstName LIKE ? ORDER BY aLastName asc");
SearchQuery.setObject(1, FirstName);
ResultSet rs=SearchQuery.executeQuery();
Any help is much appreciated, also if you could explain it to me keeping in mind I'm very new to Java and don't have a lot of programming experience yet.
The rest of my search button's code:
private void button_SearchActionPerformed(java.awt.event.ActionEvent evt) {
String FirstName = textField_FirstName.getText();
String LastName = textField_LastName.getText();
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection("jdbc:odbc:Alumni_DB");
Statement st=con.createStatement();
con.commit();
System.out.print(FirstName + " ");
PreparedStatement SearchQuery = con.prepareStatement("Select * From Alumnus_A Where aFirstName LIKE ? ORDER BY aLastName asc");
SearchQuery.setString(1, FirstName);
ResultSet rs=SearchQuery.executeQuery();
String aUID="",aFName="",aLName="",aMInitial="",aHomePhone="",aCellPhone="";
while(rs.next())
{
aUID=rs.getString(1);
aFName=rs.getString(2);
aLName=rs.getString(3);
aMInitial=rs.getString(4);
aHomePhone=rs.getString(5);
aCellPhone=rs.getString(6);
System.out.println("UID " + aUID + " First Name " + aFName + " Last Name " + aLName + " Middle Initial " + aMInitial + " Home Phone " + aHomePhone
+ " Cell Phone " + aCellPhone);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
Note: Anything with the prefix 'a' is referring to a database column

Connection from Java Application and Stored Procedure MSSQL

I have the stored procedure in SQL Sever and it has a few parameter. I would like to give the value of parameter from the combo box (in java application). I've read this code (look at below)
public static void executeSprocInParams(Connection con) {
try {
PreparedStatement pstmt = con.prepareStatement("{call dbo.uspGetEmployeeManagers(?)}");
pstmt.setInt(1, 50);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println("EMPLOYEE:");
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
System.out.println("MANAGER:");
System.out.println(rs.getString("ManagerLastName") + ", " + rs.getString("ManagerFirstName"));
System.out.println();
}
rs.close();
pstmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
But i didn't get the meaning. Is there any tutorial that give me some example just like in my case? Thanks for any reply
PreparedStatement pstmt = con.prepareStatement("{call dbo.uspGetEmployeeManagers(?)}");
pstmt.setInt(1, 50);
ResultSet rs = pstmt.executeQuery();
1) Line 1 creates a prepare statement object with your Stored Procedure. The ? is the placeholder for the input parameter to the Stored Procs
2) Line 2 sets the input param to the stored proc
3) executeQuery executes the stored proc by providing the input and get the output as a resultset.
while (rs.next()) {
System.out.println("EMPLOYEE:");
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
System.out.println("MANAGER:");
System.out.println(rs.getString("ManagerLastName") + ", " + rs.getString("ManagerFirstName"));
System.out.println();
}
rs.close();
pstmt.close();
Above lines iterate over the result set and print each record
public static void executeSprocInParams(Connection con) {
try {
PreparedStatement pstmt = con.prepareStatement("{call dbo.uspGetEmployeeManagers(?)}");//Creating a prepared statement with the string to execute your procedure.
pstmt.setInt(1, 50);//This is to set the parameter to the place holder '?'
ResultSet rs = pstmt.executeQuery();//This is to execute your procedure and put the result into a table like set
while (rs.next()) {//To check if there are any values in the set, if so the print those values
System.out.println("EMPLOYEE:");
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
System.out.println("MANAGER:");
System.out.println(rs.getString("ManagerLastName") + ", " + rs.getString("ManagerFirstName"));
System.out.println();
}
rs.close();//close the set
pstmt.close();//close the statement
}
catch (Exception e) {
e.printStackTrace();
}
}

MySQL before start of exception [duplicate]

This question already has answers here:
ResultSet exception - before start of result set
(6 answers)
Closed 5 years ago.
I get an error stating that I got an exception before start of a result set. I'm trying to get a value (score from the MySQL database) and add one to the Java rank based on the player score. This is to create a scoreboard.
So if the player's score is lower than the current score, it gets posted with rank 1. If it's higher, the program checks the score against the next entry in the MySQL database. I haven't yet implemented a feature to change all the current entries rank's to increment by 1.
Bottom Line: I'm creating a scoreboard using MySQL and Java. The Java program creates a score entry based on input, and then sends it off to the MySQL database.
System.out.println("Your score is: "+score*2+" (A lower score is better.)");
try {
// create a java mysql database connection
String myDriver = "com.mysql.jdbc.Driver";
String myUrl = "jdbc:mysql://4.30.110.246:3306/apesbridge2013";
String dbName = "apesbridge2013";
String tbName = period + "period";
Class.forName(myDriver);
Connection conn = DriverManager.getConnection(myUrl, "user", CENSORED);
next = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
ResultSet resultSet = next.executeQuery("SELECT * FROM " + tbName);
int cscore = resultSet.getInt("score");
for(int sscore = score; sscore > cscore;){
resultSet.next();
cscore = resultSet.getInt("score");
rank++;
}
stmt = conn.createStatement();
stmt.executeUpdate("insert into " + dbName + "." + tbName + " " + "values(" + rank + ", '" + name + "', " + score + ")");
stmt.close();
conn.close();
}
catch (Exception e)
{
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
}
Put resultSet.next(); right below your executeQuery line.
As stated by #hd1, you need to call ResultSet.next() after the call to executeQuery:
while (resultSet.next()) {
...
Also, better to use PreparedStatement instead of java.sql.Statement and use parameter placeholders to protect against SQL Injection attacks:
There's a problem in your for loop; the exit condition should be when there are no more rows to fetch. Your query doesn't guarantee that the exit condition will ever be met, and you may attempt to fetch past the end of the resultset. (And even when your for loop does happen to be entered, and when if the for loop does happen to be exited, the rank value derived by that loop is non-deterministic, it's dependent on the order that rows are returned by the database.
I also don't see any call to resultSet.close() or next.close().
There's so many problems here, it's hard to know where to begin.
But firstly, it would be much more efficient to have the database return the rank to you, with a query:
"SELECT COUNT(1) AS rank FROM " + tbName + " WHERE score < " + score
rather than pulling back all the rows back, and comparing each score. That's just painful, and a whole lot of code that is just noise. That would allow you to focus on the code that DOES need to be there.
Once you get that working, you need to ensure that your statement is not vulnerable to SQL injection, and prepared statements with bind variables is really the way to go there.
And you really do need to ensure that calls are made to the close() methods on the resultset, prepared statements, and the connection. We typically want these in a finally block. Either use nested try/catch blocks, where the variables are immediately initialized, like this:
try {
Connection conn = DriverManager.getConnection(...
try {
stmt = conn.CreateStatement();
String query = "SELECT COUNT(1) AS `rank` FROM " + tbName + " WHERE `score` < " + score ;
try {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
rank = rs.getInt("rank");
}
} finally {
if (rs!=null) { rs.close() };
}
} finally {
if (stmt!=null) { stmt.close() };
}
} finally {
if (conn!=null) { conn.close() };
}
Or one big try/catch block can also be workable:
} finally {
if (resultSet!=null) { resultSet.close() };
if (next!=null) { next.close() };
if (conn!=null) { conn.close() };
)
The point is, the close methods really do need to be called.

Categories