Java retrieve next similar item from database [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have the following peice of code:
Class.forName("oracle.jdbc.driver.Orac. leDriver");
Connectioncon=DriverManager.getCon. nection ("jdbc:oracle:thin:#localhost1521:","sys. tem","zed");
String pb=pricebox.getText();
int pbs=Integer.parseInt(pb);
final PreparedStatement ps=con.prepareStatement("selectitem code,remaining fromshoppingmallproducts wheretype='"+typebox.getSelectedIte(+. "',brand='"+brandbox.getSelectedIt. +'"');
final PreparedStatementps=con.prepareStat. ement("select itemcode,remainingfrom shoppingmallproducts where type=and brand=? and price>=?");
ps.setString(1(String)typebox.getSelect. editem();
ps.setString(2, (String)brandbox.getSelectedItem());
ps.setInt(3,pbs);
final ResultSet rs=ps.executeQuery();
rs.next();
itm=rs.getString("itemcode");
int rem=rs.getInt("remaining");
final String remm=String.valueOf(rem);
jta1.append("\n "+itm+"\n"+rem+"\n");
// jta is the name of the jtextpane used to append data
next.addActionListener(new ActionListener()
{
public void
actionPerformed(ActionEvent as)
{
try {
jta1.removeAll();
jta1.setText("");
rs.next();
String itm=rs.getString("itemcode");
int prc=rs.getInt("price");
int rem=rs.getInt("remaining");
String remm=String.valueOf(rem);
jta1.append("\n "+itm+"\n"+rem. +"\n");
drawimage(itm);
}
Now the question belongs to my next button.
As you can see, the next button will move the result set object to the next row. But I want it to perform it the other way. Now suppose, I choose Levis as brand price range 2000 and type casual shoes. Now suppose I have 3 such products. The first time when I click go button, it will show the first result. Now I want that when I click next, I want the second product with specified features, and so the third product.
Is there any way to do this? Please help me. I am really stuck with this as this is the last task in my college project.
I hope I have clearly explained every thing. Thanx

your question is not very clear. But I shall try to answer from what I understand.
first about rs.next();
This cursor is a pointer that points to one row of data in the ResultSet. Initially, the cursor is positioned before the first row. The method ResultSet.next moves the cursor to the next row. This method returns false if the cursor is positioned after the last row.
So rs.next() points to the result obtained from running your query. Let us say your table has 10 rows in total and then your query return 5 rows from that, depending on the conditions you have specified in the query(like brand,price etc ) . In such a case the rs will point to the 5 rows returned for your query. It will be pointed to before the first row of the result. when you do rs.next(); it should return the first row of the 5 rows returned as result. every rs.next() henceforth will return the next row from the 5 result rows. when rs points to 5th row and you do rs.next() then it will return false and you will know that not more rows exist to be returned.
if you are not getting value in this manner , most probable reason is your query. Try printing out all the rows returned from query using code
while (rs.next()) {
int itm = rs.getString("itemcode");
int price = rs.getString("price");
int remaining = rs.getString("remaining");
System.out.println(itm + "\t" + price +
"\t" + remaining );
}
this will print the result to the console for you to debug.
If this is printing the correct result then your query is correct. May be the problem is that rs value in jtextpane is incorrect and not pointing correctly as it should be.
PS : variable type of price should be double
Also if your question was just about order of returned result you could use ORDER BY with your query. it will allow the result to be returned according to the sorted order (ascending or descending based on a column ) of the table

Related

Java/MySQL - How to retrieve data from specific row

I really can't find a solution for this problem:
Here I have two ResultSets, one which always shows me the number of items stored in my database and one that retrieves all the data from it.
I would like to generate a random number and then generate a random item based on the row number/id in my database. Since I'm fairly new I'm not sure if this is an efficient approach. It doesn't look very clean to retrieve all the data and then iterate over it every time. Especially if I had like 1000 items and the randomly generated number is 999.
PreparedStatement randomSelection = con.prepareStatement("SELECT * FROM items ORDER BY RAND() LIMIT 1"); {
String name = ((ResultSet) randomSelection).getString(2);
System.out.println(name);
}
Tried calling the column itemname with the last line. However I just can't look for a good solution for this problem. Would highly appreciate any help since I'm fairly new to databases.
Thank you
EDIT: This is what I tried now and there is no output somehow
Same for
ResultSet numberOfItemsInDataBase = stmt.executeQuery("SELECT count(*) FROM items;");
// this will return a number between 0 and the number of rows - 1
int id = new Random().nextInt(numberOfItemsInDataBase.getInt(1));
ResultSet itemsInDataBase = stmt.executeQuery("select * from items order by id limit 1 offset " + id);
if (itemsInDataBase.next()) {
String item = itemsInDataBase.getString(2);
System.out.println(item);
}
If you just need a random row of the table then you can do it with plain SQL with the function RAND():
ResultSet itemsInDataBase = stmt.executeQuery("select * from items order by rand() limit 1");
if (itemsInDataBase.next()) {
item = new Item(itemsInDataBase.getString(2));
}
If you want to use the generated random number, then use it in the OFFSET clause of the sql statement:
ResultSet numberOfItemsInDataBase = stmt.executeQuery("SELECT count(*) FROM items;");
// the above query will return exactly 1 row
numberOfItemsInDataBase.next();
// this will return a number between 0 and the number of rows - 1
int id = new Random().nextInt(numberOfItemsInDataBase.getInt(1));
ResultSet itemsInDataBase = stmt.executeQuery("select * from items order by id limit 1 offset " + id);
if (itemsInDataBase.next()) {
item = new Item(itemsInDataBase.getString(2));
}
Use ORDER BY RAND() and limit the result to 1. This circumvents you having to query for the count and then ultimately iterate through the ResultSet until you find the random entry.
try (ResultSet randomSelection = connection
.preparedStatement("SELECT * FROM items ORDER BY RAND() LIMIT 1")) {
if (randomSelection.next()) {
String name = randomSelection.getString(2);
}
}
You can use the limit function to get the item.
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1). So in your case the offset can be the the random generated id minus one and maximum number of rows is 1:
select * from items LIMIT {id-1},1; # Retrieve row (id-1)

PreparedStatement.execute() returns false even there is resultset in SQL server?

My sql query consists of 5 part which are highly connected to each other. First part creates a temporary table, second part uses that temporary table and creates another temporary table, third part uses the temporary table that created in second part and again creates another temporary table. And the 4th part select some data from 3rd temporary table and 5th part selects the count of 3th temporary table.
Since temporary tables are only usable within a preparedStatement (what I mean is that a temporary table which created by a preparedStatement are not usable from another preparedStatement, I tried that before it is okey) I need to do that within a prepare statement.
So the first 3 part creates temporary tables because of that after setting the parameters to preparedStatement I run preparedStatement.execute() 3 times(I also tried 1....x times) and then I run the preparedStatement.execute() but it returns false which means that there is no resultset. Why is that?
PreparedStatement preparedStatement = conn.prepareStatement("select * into #tmp from tablex where ...\n" +
" select * into #tmp2 from #tmp where ...\n" +
" select * into #tmp3 from #tmp2 where ...\n" +
" select * from #tmp3\n" +
" select count(*) from #tmp3");
Above, I added a simple illustration. Here I need to get the result of 4th and 5th query with prepared statement. How can I do that?
The statements you're executing produce the following results:
An update count
An update count
An update count
A result set
A result set
The meaning of the boolean false returned by execute(String) is:
true if the first result is a ResultSet object; false if it is
an update count or there are no results
This means that you need to use getUpdateCount() to obtain the (first) update count, and getMoreResults() to get the next result (again, this returns a boolean with the same meaning). Only if execute() or getMoreResults() returns false and getUpdateCount() returns -1 are there no more results.
You need to do something like:
boolean nextResultSet = statement.execute(...);
int resultSetCount = 0;
while (true) {
if (nextResultSet) {
resultSetCount++;
try (ResultSet rs = statement.getResultSet()) {
// Do something with result set
}
} else {
int updateCount = statement.getUpdateCount();
if (updateCount == -1) {
// no more results
break;
}
// do something with update count
}
nextResultSet = statement.getMoreResults();
}
You can probably skip part of this complexity by adding SET NOCOUNT ON as the first statement you execute; then you'll not get the update counts and only need to handle the two result sets.

Can I compare resultsets like this? I'm facing the below error

I have 2 ResultSets. 1st ResultSet contains the records from table1 from database1 and 2nd ResultSet contains the records from table2 from database2. I need a list of records from resultset1 which are not present in resultSet2. For this I wrote this logic but it is not working and throwing me the following error.
java.sql.SQLException: Invalid operation for read only resultset: deleteRow
if ( table1ResultSet != null )
{
while ( table1ResultSet.next() )
{
final String table1Record = table1ResultSet.getString( 1 );
if ( table2ResultSet != null )
{
while ( table2ResultSet.next() )
{
final String table2Record = table2ResultSet.getString( 1 );
if ( table1Record.toString().equalsIgnoreCase( table2Record.toString() ) )
{
table1ResultSet.deleteRow();
break;
}
}
}
}
}
return table1ResultSet;
That exception says what the problem is - your result set doesn't support delete. In order to have updateable result set there are some requirements:
When you prepare statement did you make it with ResultSet.CONCUR_UPDATABLE?
A query can select from only a single table without any join operations.
The query must select all non-nullable columns and all columns that do not have a default value. A query cannot use "SELECT * ". Cannot select derived columns or aggregates such as the SUM or MAX of a set of columns.
You might want to move the results sets into Java sets before working doing what you are doing though because using deleteRow will actually delete the row from the database (unless that's the expected result)
There is another problem with your code though. Even if delete works your code will fail on the second iteration of result set 1 because you never reset table2ResultSet and for the second iteration there won't be more results in table2resulset.
But on top of all that. Why would you go through all that hussle and get all that rows that you don't need instead of doing it with one single query like:
select * from table 1 where id not in select id from table 2
or
delete from table 1 where id not in select id from table 2
if that's the goal
Your logic:
Assumes the records come in some order (which may or may not be true, depending on your SQL)
Consumes the entire result set 2 for each row of result set 1, which is unlikely your intent
Deletes things, which is also not what you mentioned in the question
Your question can be implemented easily as such:
Set<String> list1 = new HashSet<>();
while (table1ResultSet.next())
list1.add(table1ResultSet.getString(1).toLowerCase());
while (table2ResultSet.next())
list1.remove(table2ResultSet.getString(1).toLowerCase());
System.out.println(list1);
This will print all the values (without duplicates) that are present in the first result set, but not in the second.

resultSet iterating through rows within the same line

Ok that may not make much sense so I'll try and clarify with code, I've got a basic Result set like so: -
ResultSet results = stmt.executeQuery(constants.execQueueSQL());
I then want to iterate through this with a while loop like so: -
while (results.next()){
String val1 = results.getString("col 1");
String val2 = results.getString("col 2");
String val3 = results.getString("col 3");
}
Now, when I debug this within eclipse I can see that before executing the while line the currentRow is already showing as 1 in results, and as I step to each line within the while the currentRow count increases by 1!!
I know that I have 4 rows returned but by the time I get to retrieving col 3 I'm already out, and all subsequent values are wrong as they are being obtained from separate lines, why is this...?

Is it safe to delete rows from Android SQLite database while iterating cursor

For example:
public void removeStaleMovies(Set<String> updatedMovieList) {
Cursor cur = this.getReadableDatabase().rawQuery("SELECT id, title, year FROM movie", null);
cur.moveToFirst();
while (!cur.isAfterLast()) {
String title = cur.getString(1);
String year = cur.getString(2);
if (!updatedMovieList.contains(title + "-" + year)) {
// delete the row where 'id' = cur.getString(0)
// OR, delete the row using the object at the cursor's current position, if that's possible
// OR, if deletion isn't safe while iterating, build up a list of row id's and run a DELETE statement after iteration is finished
}
}
}
Is deletion safe to do? Or can it result in some unpredictable behavior? I am aware of this similar question, but I'm still unsure.
From a code safety standpoint, this should be OK, assuming that the result set of your query is less than 1MB. In that case, the Cursor holds in heap space the entire result set, so it is insulated from any changes to the underlying database.
That being said, you may want to build up a list of rows to delete, simply so you can delete them in a single statement, rather than a bunch of individual statements (though wrapping those individual statements in a transaction may give you similar performance characteristics).

Categories

Resources