Unknown record number while executing SQLite query - java

When I am executing a SQLite query (using sqlite4java) I am following the general scheme of executing it step by step and obtaining one row at a time. My final result should be a 2-D array, whose length should correspond to the amount of records. The problem I am facing is the fact that I don't know in advance how many records are to be returned by my query. so I basically store them in an ArrayList and then copy pointers to the actual array. Is there a technique to somehow obtain the number of records to be returned by the query prior to executing it fully?

My final result should be a 2-D array, whose length should correspond to the amount of records.
Why? It would generally be a better idea to make the result a List<E> where E is some custom type representing "a record".
It sounds like you're already creating an ArrayList - so why do you need an actual array? The Collections API is generally more flexible and convenient than using arrays directly.

No, if using JDBC. You can, however, first do a COUNT() query, and then the real query.

Related

Better to query once, then organize objects based on returned column value, or query twice with different conditions?

I have a table which I need to query, then organize the returned objects into two different lists based on a column value. I can either query the table once, retrieving the column by which I would differentiate the objects and arrange them by looping through the result set, or I can query twice with two different conditions and avoid the sorting process. Which method is generally better practice?
MY_TABLE
NAME AGE TYPE
John 25 A
Sarah 30 B
Rick 22 A
Susan 43 B
Either SELECT * FROM MY_TABLE, then sort in code based on returned types, or
SELECT NAME, AGE FROM MY_TABLE WHERE TYPE = 'A' followed by
SELECT NAME, AGE FROM MY_TABLE WHERE TYPE = 'B'
Logically, a DB query from a Java code will be more expensive than a loop within the code because querying the DB involves several steps such as connecting to DB, creating the SQL query, firing the query and getting the results back.
Besides, something can go wrong between firing the first and second query.
With an optimized single query and looping with the code, you can save a lot of time than firing two queries.
In your case, you can sort in the query itself if it helps:
SELECT * FROM MY_TABLE ORDER BY TYPE
In future if there are more types added to your table, you need not fire an additional query to retrieve it.
It is heavily dependant on the context. If each list is really huge, I would let the database to the hard part of the job with 2 queries. At the opposite, in a web application using a farm of application servers and a central database I would use one single query.
For the general use case, IMHO, I will save database resource because it is a current point of congestion and use only only query.
The only objective argument I can find is that the splitting of the list occurs in memory with a hyper simple algorithm and in a single JVM, where each query requires a bit of initialization and may involve disk access or loading of index pages.
In general, one query performs better.
Also, with issuing two queries you can potentially get inconsistent results (which may be fixed with higher transaction isolation level though ).
In any case I believe you still need to iterate through resultset (either directly or by using framework's methods that return collections).
From the database point of view, you optimally have exactly one statement that fetches exactly everything you need and nothing else. Therefore, your first option is better. But don't generalize that answer in way that makes you query more data than needed. It's a common mistake for beginners to select all rows from a table (no where clause) and do the filtering in code instead of letting the database do its job.
It also depends on your dataset volume, for instance if you have a large data set, doing a select * without any condition might take some time, but if you have an index on your 'TYPE' column, then adding a where clause will reduce the time taken to execute the query. If you are dealing with a small data set, then doing a select * followed with your logic in the java code is a better approach
There are four main bottlenecks involved in querying a database.
The query itself - how long the query takes to execute on the server depends on indexes, table sizes etc.
The data volume of the results - there could be hundreds of columns or huge fields and all this data must be serialised and transported across the network to your client.
The processing of the data - java must walk the query results gathering the data it wants.
Maintaining the query - it takes manpower to maintain queries, simple ones cost little but complex ones can be a nightmare.
By careful consideration it should be possible to work out a balance between all four of these factors - it is unlikely that you will get the right answer without doing so.
You can query by two conditions:
SELECT * FROM MY_TABLE WHERE TYPE = 'A' OR TYPE = 'B'
This will do both for you at once, and if you want them sorted, you could do the same, but just add an order by keyword:
SELECT * FROM MY_TABLE WHERE TYPE = 'A' OR TYPE = 'B' ORDER BY TYPE ASC
This will sort the results by type, in ascending order.
EDIT:
I didn't notice that originally you wanted two different lists. In that case, you could just do this query, and then find the index where the type changes from 'A' to 'B' and copy the data into two arrays.

how to initialize java array size to store database ResultSet data?

I'm new to java but my experience with Matlab and C trained me to ALWAYS pre-allocate memory for an array variable before filling that variable inside a loop (e.g. For loop, While loop, etc).
I find myself retrieving data from a database in Java using ResultSet. A quick search shows there's no way to obtain the number of rows in the ResultSet without stepping through it. Thus the basic question: how to pre-allocate array length of a Java variable intended to store the results of the ResultSet query, without knowing the number of rows in that ResultSet?
What's the conventional wisdom? For example, if the ResultSet contains two columns of data, how to place each column into an separate Java array variable?
UPDATE 1: Some background -- I need to place everything returned by the ResultSet into an object so that I may pass that object to a non-Java (e.g. ActionScript) program that communicates with the Java program via this object's contents.
UPDATE 2: Here's the documentation on the conversion rules from Java to non-Java (e.g. ActionScript). Perhaps
http://help.adobe.com/en_US/LiveCycleDataServicesES/3.1/Developing/WSc3ff6d0ea77859461172e0811f00f6eab8-7ffdUpdate.html
Why are you adding it to arrays? You can easily iterate through the ResultSet, transform the results to the appropriate Objects, and add them to an ArrayList... gives you much more flexibility than adding to an array.
But if you really need the number of rows, I think you'll need to run a count query before running your original one.
EDIT: From the documentation you linked, it would seem that if you use a Java ArrayList you'd end up with an ActionScript mx.collections.ArrayCollection object instead of the ActionScript Array object you'd get if you used a Java array. Your choice which one to use, just convert List -> array if you can't change your ActionScript code...:
List<MyObject> myList = new ArrayList<MyObject>();
... populate myList from ResultSet ...
MyObject[] array = myList.toArray(new MyObject[myList.size()]);
as what Marcelo said, ArrayList is a better option for this problem, but instead of executing a COUNT query to know how many rows is returned, you can trick it by using:
rs.last();
rs.getRow();
then gat back to the first row after,.

PreparedStatement to insert unknown amount of values with unknown types

I have a method insert() which inserts a list of values into a table which is chosen by the user.
The problem is that since the user gets to choose the table, the method does not know how many values that are to be inserted and of which type they are. I've solved the variable amount of values with a loop that uses a stringbuilder to insert the correct amount of "?"-chars into the values part of the query.
I also have a loop that splits the values received into a String array, but I then have a problem with ints being processed like strings. Can I get around this using some trick with sql-syntax, or do I need to fetch information about which kind of data type each value is?
And if I have to fetch info about the data types, how do I do that? (Preferably an sql query that returns nothing but the types since I want to use the result directly in my java code).
Firstly, what I suspect you are doing is wrong, or certainly sub-optimal.
Assuming you were adamant this is how you want to go about it, you need to retrieve a row from your table and then call getMetadata() on the ResultSet.
You would end up with something like:
rs.getMetaData().getColumnTypeName(int column)
Once you know the column type, you can parse/sanitize your user entered data accordingly.

Is there any difference in performance of resultset and Scrollable ResultSet?

In my application I have to fetch records and need to put them in to 2D array. I have to fire two queries first to find out the count so that I can initialize the array and second is to fetch the data. It results in performance hit. I need solution to improve the performance.
Thanks.
I have to fire two queries first to
find out the count so that I can
initialize the array and second is to
fetch the data.
You can combine your 2 queries as:
select *,(select count(*) from table) as counting from table;
Also consider using a suitable Collection, such as List<List<Object>>. For improved type-safety, consider using Class Literals as Runtime-Type Tokens; the query example is near the bottom.

How to insert values result set into hashmap without iterating in Java 1.4?

I want to validate a value against values retrieved from a result set's first column. I have to do the same validation operation approximately 1000 times. So, I want to decrease the time complexity of this comparison from O(n) to constant. Is there some function through which I can put all of the values of result set's column into a hashmap without iterating?
Short answer: no
(I assume you're talking about a JDBC ResultSet). No, but that isn't a problem for you. It took O(n) to generate the ResultSet, so you shouldn't be worried about using O(n) more time to put them in a hashmap, or just do the validation against the whole ResultSet directly.
Is it possible to do the validation as part of the database query itself (in the where clause) by passing the value from your code to the query ?

Categories