SQLite: executeQuery() returns an empty result set - java

The following Java code returns an empty result set but the SQL shows that there is data in the table:
#Override
public List<Category> list() {
List<Category> list = new ArrayList<>();
if (!connection.isPresent()) {
return list;
}
Connection con = connection.get();
try {
Statement stmnt = con.createStatement();
ResultSet rs = stmnt.executeQuery(LIST_SQL);
while (rs.next()) {
System.out.println("Got a record"); // DEBUG
int id = rs.getInt(1);
String description = rs.getString(2);
list.add(new Category(id, description));
}
} catch (SQLException e) {
LOG.error("Error retrieving Category list", e);
return list;
}
return list;
}
LIST_SQL is:
SELECT id, description FROM category
If I copy this query into sqlite3 and execute it, several rows are returned. connection works with other queries (but they are prepared statements and not an executeQuery). There is no error. "Got a record" is never printed.
Any ideas about what could be going wrong?

Sorry guys. My list() method was never getting executed! Why is another question. Thanks for all your responses.

It doesn't look like you remembered to include the ";" in the LIST_SQL string. Semi-colon is required to end the query statement.

Related

Problem with diacritic, getting data from database java

I have MySQL database, where I have saved data and some words have diacritics.
This is my function how to get data from database.
public List<RowType> getData(String query){
List<RowType> list = new ArrayList<>();
try{
connect();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
while(resultSet.next()){
StringBuilder str = new StringBuilder();
for(int i = 1; i <= getCountColumns(resultSet); i++){
if(i==1) str.append(resultSet.getString(i));
else str.append("," + resultSet.getString(i));
}
list.add(new RowType(str.toString()));
}
}
catch(Exception e){
System.out.println("Chyba při získavání údajů z databáze.");
System.out.println(e);
Console.print("Chyba při získavání údajů z databáze.");
Console.print(e.toString());
}
finally{
disconnect();
}
return list;
}
As parameter i send this query.
List<RowType> list = connection.getData("Select id from countries where name = 'Česko'");
But it doesn´t find anything, because i have diacritic in the query ("Česko"). I try it without diacritic and it works. So don´t you know how to fix it to work with accents too?
Can you try to add a few more queries before executing your main query?
so it will look something like:
connect();
Statement statement = connection.createStatement();
String query2 = "SET NAMES 'utf8'";
statement.execute(query2);
query2 = "SET CHARACTER SET 'utf8'";
statement.execute(query2);
ResultSet resultSet = statement.executeQuery(query);
if the above does not work for you, then maybe there is an issue with your database settings; if that's the case, you can refer to the answer here

SQLite DELETE query won't delete from database

Here's my code for the addStudent:
#FXML
private void addStudent(ActionEvent event) {
// sql query to insert data into students at ID, first name, last name, email and DOB
String sqlInsert = "INSERT INTO students(id,fname,lname,email,DOB) VALUES (?,?,?,?,?)";
try {
Connection conn = dbConnection.getConnection();
PreparedStatement stmt = conn.prepareStatement(sqlInsert);
// add the data in the right column
stmt.setString(1, this.id.getText());
stmt.setString(2, this.firstname.getText());
stmt.setString(3, this.lastname.getText());
stmt.setString(4, this.email.getText());
stmt.setString(5, this.dob.getEditor().getText());
stmt.execute();
conn.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
And here's my code for removeStudent:
#FXML
private void removeStudent(ActionEvent event) {
try {
// sql query to delete data from the database
String sqlRemove = "DELETE FROM students WHERE id = ?";
// open a connection to the database and use PreparedStatement to
// initialize the query.
Connection conn = dbConnection.getConnection();
PreparedStatement delete = conn.prepareStatement(sqlRemove);
// information needed to delete the row
delete.setString(1, selectStudent());
// execute and delete
delete.executeUpdate();
// close the connection
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
// update table after deleting
loadStudentData(event);
}
The picture above is the view of my table. I hit LoadData and my table values show up. I want to be able to click on a row(student) and hit Delete Student to remove it.
Helper method for removeStudent:
private String selectStudent() {
String result = "";
try {
String sqlSelect = "SELECT id FROM students";
Connection conn = dbConnection.getConnection();
ResultSet rs = conn.createStatement().executeQuery(sqlSelect);
result = rs.getString(1);
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
return result;
}
I'm pretty sure it has to do with when I "click" on a row, the id value for that isn't being held anywhere so when I hit "Delete" nothing is being given for it to Delete.
I don't know. Any advice would be awesome. :D
First edit: nothing is assigned to delete.setString(1, this.id.getText()). When I click on the row and hit delete, nothing is happening because there's nothing being assigned to id when I click on the row. The query string DOES work however when I physically give it an ID to delete. Also verified that the button does work; it prints out a lovely message for me with a good ol' System.out.println("expletive");
Second edit: Ok, so I updated the removeStudent code and now all I get is the string "null" returned. Nothing deletes. Nothing updates. Nothing is happening except I get "null" in the console.
Third edit: Getting closer! With the realization that the removeStudent isn't being given an ID to delete, I decided to create a private helper method that will do a SELECT query. Now, when I hit delete, it'll delete....but from the top, and not at where I want it selected. The code is above.
Fourth edit: Getting even closer! So, I figured out how to capture the row I click on within the table and I can delete......however, because of my sqlRemove command, I'm deleting by id so if I click on a row with index 3, then ONLY the row within the table that has an id of 3 will be deleted, nothing else. I gotta re-write how the sqlRemove command is worded.
I fixed it:
private String selectStudent() {
// initial value for result to return
String result = "";
// grab the index of the row selected on the table
int initial = studenttable.getSelectionModel().getSelectedIndex();
try {
// SELECT query to execute
String sqlSelect = "SELECT id FROM students";
Connection conn = dbConnection.getConnection();
ResultSet rs = conn.createStatement().executeQuery(sqlSelect);
// while there's a next row
while(rs.next()) {
// set temp to equal the id rs.next() is currently on
String temp = rs.getString("id");
// get the row id - 1 since we start at 0
int temp1 = rs.getRow() - 1;
// if temp1 is equal to the index we selected
if(temp1 == initial) {
// make it equal to result
result = temp;
}
}
// close the connection
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
// return the row to delete
return result;
}
What's going on is in the comments. I finally figured out how to pass the value from a selected row and compare it to a row. Once I get the correct row to pass, I give it to the delete function to remove.
After a day in a half.............but I love it, so. Yeah.

Prepared Statement only retrieves the first row

I'm developing a web application in which users can insert a number of "products". These products will be inserted in a MySQL database. I have a problem when I try to retrieve data from a table of my database. Here is my method:
public ArrayList<Product> getProductByAppId(int appId) {
ArrayList<Product> list = new ArrayList<Product>();
String query = "select prodId from app_prod where appId = ?";
try {
preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, appId);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
Product item = getProductById(resultSet.getInt("prodId"));
list.add(item);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
This method simply gets an int as a parameter and retrieves from the table app_prod all the objects I have stored. The method getProductById it's an helper method and it works properly. When I try to debug my code, I see that I enter in the while cycle only once! So all I see is the very first element in my DB, but I have more than a single product in my DB.
To make things shorter, I've omitted methods to open and close connection because they work properly.
I think the error is something very obvious, but I can't really see it.
OK the problem is the following:
resultSet is declared as a global variable and is being used by both methods.
When the second method changes its contents and gets through it by :
resultSet.next();
And reaches the end of it:
The main outer loop tries to do resultSet.next(), it directly exits from the loop since it had already reached its end beforehand in the getProductById method.
List<Product> list = new ArrayList<>();
try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
preparedStatement.setInt(1, appId);
try (resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) {
Product item = getProductById(resultSet.getInt("prodId"));
list.add(item);
}
return list;
}
} catch (Exception e) {
e.printStackTrace();
}
The try-with-resources ensure that statement and resultset are closed (even despite the return).
Also now the variables are local. And that might be the problem: maybe you reused those global fields in getProductById. resultSet would be my guess. (Pardon me.)

How do I return multiple rows from a JDBC method?

I am currently learning JDBC and can successfully query and retrieve data from a MysQL database. But I would like to run this as a method and return the resultset rows from the method to the calling program.
So far I think I have made an appropriate method but am stuck returning the resultset as an object. Eclipse gives me the following error for the return type:
Object cannot be resolved to a type
Here is the method:
public object getAllPosts(int catID) throws Exception{
try{
this.catID = catID;
sql = "SELECT post_id, post_title, post_content, post_date FROM crm_posts WHERE cat_id = ? LIMIT ?";
prep = conn.prepareStatement(sql);
prep.setInt(1, catID);
prep.setInt(2, 3);
// execute statement
rs = prep.getResultSet();
} catch(Exception e){
e.printStackTrace();
}
return rs;
}
What is the return type I should use or is there a better way of doing this?
EDIT:
As stated in the comments it was a (annoying) typo. Object with a capital O.
If you're not going to return a ResultSet or Object object, then you should define your return type. You could create your own Post object for each row in the ResultSet, put those objects in a list, and return the list.
This is how you do it
public List<MyClassThatRepresentsTableInDatabase> getAllPosts(int catID) throws Exception{
try{
this.catID = catID;
sql = "SELECT post_id, post_title, post_content, post_date FROM crm_posts WHERE cat_id = ? LIMIT ?";
prep = conn.prepareStatement(sql);
prep.setInt(1, catID);
prep.setInt(2, 3);
// execute statement
rs = prep.getResultSet();
List<MyClassThatRepresentsTableInDatabase> ret=new ArrayList<>();
while(rs.hasNext()){
MyClassThatRepresentsTableInDatabase item=
new MyClassThatRepresentsTableInDatabase();
item.setId(rs.getLong("post_id");
item.setName(rs.getString("post_title");
item.setContentd("post_content");
//etc..
ret.add(item);
}
return ret;
} catch(Exception e){
e.printStackTrace();
}
return new ArrayList();
}
Excecute your query in ResultSet and loop it to get your results.
Use the following line of codes :
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery(sql);
while(rs.next())
{
out.println(rs.getString("//Your Column name"));
}

JDBC ResultSet is giving only one row although there are many rows in table?

I am having many rows in table and I ran the same query on my database which is MySql but java ResultSet is only giving the first row of the table. Here is my code.
public ArrayList<String> getAllAlbumsName(Integer uid) {
ArrayList<String>allAlbumsName = new ArrayList<String>();
try {
String qstring = "SELECT albumname FROM picvik_picture_album WHERE " +
"uid = '" + uid + "';";
System.out.println(qstring);
connection = com.picvik.util.MySqlConnection.getInstance().getConnection();
ptmt = connection.prepareStatement(qstring);
resultSet = ptmt.executeQuery();
if(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
resultSet.close();
ptmt.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
return allAlbumsName;
}
if(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
If you would like to get all rows, it should be:
while(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
The while statement continually executes a block of statements while a particular condition is true
Note: As #BalusC commented, your code would introduce SQL Injection attack, it is better to use ptmt.set... Instead of constructing SQL String manually.
try while(resultSet.next()) {
instead of if (resultSet.next()) {
Change if (resultSet.next()) { to while (resultSet.next()) {

Categories