I'm trying to understand how to save result from SQL queries in android to an arraylist. Actually I find a few questions but none of them can answer why my code is wrong. So here is what I'm trying to do :
String query = null;
query = "SELECT * FROM users WHERE objectId = "+objectId+" AND serverName "+serverName;
SQLiteDatabase db;
// Insert results from query in database.
ArrayList <String[]> result = new ArrayList<String[]>();
ResultSet rs = db.execSQL(query);
int columnCount = rs.getMetaData().getColumnCount();
while(rs.next())
{
String[] row = new String[columnCount];
for (int i=0; i <columnCount ; i++)
{
row[i] = rs.getString(i + 1);
}
result.add(row);
}
And the error is saying that I cannot convert void to ResultSet.
Any suggestions how to fix that or which is the right way to do this.
Thanks in advance
Once your database is open for reading use db.query or db.rawQuery to get a cursor that can be used to create your ArrayList
cursor = db.rawQuery(<query>, null);
if(cursor.getCount() > 0)
{
cursor.moveToFirst();
//add to list here
}
Related
ok I just followed an instruction that I should do this to retrieve sql data from database but it just cuts to there so far I have this inside my databasehelper class.
public void getIconResource(String tblName)
{
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource,null); //null for conditions
if(cursor.moveToFirst())
{
do
{
int resource = cursor.getInt(3);
}
while (cursor.moveToNext());
}
db.close();
}
So somehow this does is it get all the values of my tables 4th column which contains an int... how do I retrieve the value in my MainActivity and save it in an array of integers?
just add everything in a ArrayList and return the arraylist
simply call the method in your main activty
public ArrayList<Integer> getIconResource(String tblName)
{
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource,null); //null for conditions
ArrayList data= new ArrayList<>();
if(cursor.moveToFirst())
{
do
{
int resource = cursor.getInt(3);
data.add(resource);
}
while (cursor.moveToNext());
}
db.close();
}
return data;
}
Well, as you have it, the variable resource is scoped only to the while loop. Even if it wasn't it would constantly get overwritten on each loop iteration.
Instead, you should declare a collection higher up and Add each value to it during your while loop. You could also redefine your function to return the collection if integers.
public List<int> getIconResource(String tblName)
{
SQLiteDatabase db = this.getReadableDatabase();
List<int> myVals = new List<int>();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource, null); //null for conditions
if (cursor.moveToFirst())
{
do
{
myVals.Add(cursor.getInt(3));
}
while (cursor.moveToNext());
}
db.close();
return myVals;
}
Also, as a note... string concatenation of a SQL query is a recipe for disaster. Look up SQL Injection and best practices to avoid it before continuing further. It is worth the time to get into good habits early on.
EDIT / ADDENDUM
Unless you also limit your result set returned from your table query, you will be getting every record. The function you have here really has no practical use and would likely cause more problems than any benefits it may have. I would suggest, as an example of a more usable function that returns a specific IconResource based on the IconId:
public int getIconResource(int iconId)
{
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "select IconResource from IconTable where IconId = ?";
PreparedStatement pstmnt = db.prepareStatement(getresource);
pstrmnt.setString(1, iconId);
ResultSet rset = db.executeQuery();
int iconResource;
if (rset.next())
iconResource = rset.getInt("IconResource");
db.close();
return iconResource;
}
Of course, the above is making assumptions of your table structure.
Using the above, in your code elsewhere, you would simply call this function with the IconId and use the output however needed:
int iconResource = getIconResource(5); // returns the IconResource for IconId = 5
The above prevents any possible SQL Injection attacks by using a parameterized query and avoiding the use of dynamic concatenated strings sent to your SQL server.
You may try out the following code:
public List<Integer> getIconResource(String tblName)
{
List<Integer> list = new ArrayList<Integer>();
list.clear();
SQLiteDatabase db = this.getReadableDatabase();
String getresource = "Select * from " + tblName;
Cursor cursor = db.rawQuery(getresource,null); //null for conditions
if(cursor.moveToFirst())
{
do
{
int resource = cursor.getInt(3);
list.add(resource);
}
while (cursor.moveToNext());
}
db.close();
return list;
}
Then call this method in MainActivity and store the List in another Integer type list.
databasehelper dbhelper;
List<Integer> newList = dbhelper.getIconResource("Your tablename");
fot(int i = 0 ; i< newList.size() ; i++){
int yourValue = newList(i);
}
I have a list of items queried from my database. This list has two words in each item, the two words are separated by a space. I now want to get access to only the last word after the space.
This the query from my database
public List<String> getList(){
List<String> array = new ArrayList<String>();
String selectQuery = "SELECT * FROM " + TABLE_LIST;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
ArrayList<ArrayList<String>> row = new ArrayList<ArrayList<String>>();
if (cursor .moveToFirst()) {
;
do {
String listName = cursor.getString(cursor.getColumnIndex(ITEM_A));
array.add(listName);
}while(cursor.moveToNext());
}
cursor.close();
return array;
}
Accessing the items from the query
List<String> m = new ArrayList<String>();
m = dbHelper.getList();
System.out.println(m);
This gives the below output
[itemOA AITEME,itemOD BITEMD,itemOC CITEMS, itemOB DTEM]
I however wants to get the last words of the list,
[AITEME, BITEMD, CITEMS ,DTEM]
Thanks for helping.
I think you could restructure your code to save from having to do this, but:
String substr = myString.substring(startIndex);
Will work as long as you always have a known starting point (if it's always going to start with "itemOA" or 6 characters + a single whitespace)
Please check following code:
List<Database> zaznamy = new ArrayList<Database>();
String selectQuery = "SELECT X FROM Data WHERE LEVEL_1 =-24 AND LEVEL_2 =-48 AND LEVEL_3 =-55 AND LEVEL_4 =0";
File dbfile = new File("/sdcard/rtls/Databases/"+DBName );
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
Cursor cursor = db.rawQuery(selectQuery,null);
String bodX="empty";
if (cursor.moveToFirst())
{
do {
Database zaznam = new Database();
zaznam.setX(Integer.parseInt(cursor.getString(10)));
zaznamy.add(zaznam);
} while (cursor.moveToNext());
for (Database cn : zaznamy)
{
Log.d("X: ", Integer.toString(cn.getX()));
bodX = (cn.getX()+ "//").toString();
Log.d("X", bodX);
}
}
It says it Couldn't read row 0, col 10 from CursorWindow. I´ve tested the database with SQLite browser. Database has exactly 1 X at column 10, row 0. SQL query is working correctly I believe. Can someone tell me, why it cant be read? Or where is mistake?
EDIT:
corrected the code to:
do {
Database zaznam = new Database();
zaznam.setX(cursor.getInt(10));
zaznamy.add(zaznam);
} while (cursor.moveToNext());
because of integer value of 10th column, but still no luck. Same error
Your query has only one column in projection - column 'X'. That column has index 0 in query projection so to make your code work change your loop to looks like this:
do {
Database zaznam = new Database();
zaznam.setX(cursor.getInt(0));
zaznamy.add(zaznam);
} while (cursor.moveToNext());
To avoid that kind of problems in the future use following:
cursor.getInt(cursor.getColumnIndexOrThrow("X");
Remember that column index is related to query projection and not the sequence of columns in your database, so for example when you write "select B A C from SOME_TABLE" column B will have index 0 and column A will have index 1 etc. even if in your database they are in alphabetical order A B C.
I was having the same issue. For me. A simple work around may be:
// query database and populate an ArrayList
private void getDataFromDatabase() {
Cursor cursor = dbConnector.getSomeData();
if (cursor.getCount() > 0) {
cursor.moveToFirst();
for(int i = 0; i < cursor.getCount(); i++) {
// get column data from database and add it to ArrayList
anArrayList.add(cursor.getString(cursor.getColumnIndexOrThrow("Attr")));
cursor.moveToNext();
} // end for
} // end if
dbConnector.close();
} // end getDataFromDatabase
WHERE "Attr" is the Attribute/column name you wish to query and the anArrayList is the ArrayList you want to store the data in.
I'm making an app that records the timestamp of touchscreen actions made my the user.
Then, after recording the readings in an SQLite table, I take the average of each column at the end. However, I'm getting an error:
E/AndroidRuntime(1344): java.lang.NumberFormatException: Invalid long: "1.40024e+08"
This happens when I try to take the average of each column, which I'm doing like so:
public long[] getAvg()
{
String selectQuery = "SELECT AVG(dwell_1), AVG(dwell_2), AVG(dwell_3), AVG(dwell_4), AVG(dwell_5), AVG(dwell_6), AVG(dwell_7), AVG(dwell_8), AVG(dwell_9), AVG(flight_12), AVG(flight_23), AVG(flight_34), AVG(flight_45), AVG(flight_56), AVG(flight_67), AVG(flight_78), AVG(flight_89) FROM " + TABLE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
long[] row = new long[17];
if (cursor.moveToFirst()) {
for (int j=0; j<17; j++)
row[j] = Long.parseLong(cursor.getString(j));
}
return row;
}
It seems to be a function of the way the SQLite query displays the results. Is there any way I can circumvent/solve this? I require the precision by the way, so I can't use int or something else instead.
Oddly enough, when I run a query to just straight up display every record in the table, it works fine.
Any help will be greatly appreciated. Thanks in advance!
I believe SQLiteAVG() function returns a float value which you are trying to parse it as Long, hence the exception.
Try this :
public long[] getAvg()
{
String selectQuery = "SELECT AVG(dwell_1), AVG(dwell_2), AVG(dwell_3), AVG(dwell_4), AVG(dwell_5), AVG(dwell_6), AVG(dwell_7), AVG(dwell_8), AVG(dwell_9), AVG(flight_12), AVG(flight_23), AVG(flight_34), AVG(flight_45), AVG(flight_56), AVG(flight_67), AVG(flight_78), AVG(flight_89) FROM " + TABLE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
long[] row = new long[17];
if (cursor.moveToFirst()) {
for (int j=0; j<17; j++)
row[j] = cursor.getLong(j);
}
return row;
}
SQLite returns float result, which you are trying to save to long.
Possible solutions:
Use float/double variables on Java side.
Or force SQLite to output integer/long using
SELECT CAST(avg(field) AS INTEGER) AS avg_field...
In your case, result should still fit into Java long if original was SQLite INTEGER.
Consider a simple method that fetches the average rating of an entity. The rating float value is stored between 0.0 to 5.0.
public static float getAverageReviews(SQLiteDatabase db) {
String selectQuery = "SELECT SUM(stars) * FROM " + DatabaseHelper.TABLE_STORE_REVIEWS;
Cursor c = db.rawQuery(selectQuery, null);
int count = c.getCount();
float totalSum = 0;
if(count > 0 && c.moveToFirst())
{
do {
String result = c.getString(c.getColumnIndex(StoreReviews.KEY_STARS));
totalSum += Float.parseFloat(result);
} while (c.moveToNext());
}
else {
return 0;
}
return totalSum/count;
}
I want to store the values of a particular column in the array, As I am a fresher I don't know how to do this. I am getting values from sqlite as
1
2
123
432
3
5
I want to store these values in string array. Please tell me I am not finding any appropriate example by googling about this.. thanx in advance.
public void fun(String query){
Cursor cursor = db.rawQuery(query, null);
try{
String[] arr = new String[cursor.getCount()];
if(cursor != null){
while(cursor.moveToNext()){
for(int i = 0; i < cursor.getCount(); i++){
arr[i] = cursor.getString(0).trim();
}
cursor.moveToNext();
}
cursor.close();
}
}finally{
cursor.close();
}
}
Here query is
SELECT <COLUMN_NAME> FROM <TABLE_NAME> WHERE <CONDITION>;
I think I am doing it wrong please correct my errors...
I consider using rawQuery is a bad habit, try to avoid this(except in extreme cases)
Try as follows to solve your problem, hope this will help you:
public ArrayList<String> getAllStringValues() {
ArrayList<String> yourStringValues = new ArrayList<String>();
Cursor result = db.query(true, YOUR_TABLE,
new String[] { YOUR_COLUMN_NAME }, null, null, null, null,
null, null);
if (result.moveToFirst()) {
do {
yourStringValues.add(result.getString(result
.getColumnIndex(YOUR_COLUMN_NAME)));
} while (result.moveToNext());
} else {
return null;
}
return yourStringValues;
}
Use this method in YourCustomDBManager class. consider NotePad example of android developers sites example programmers guide for getting better concept. It will help you to learn how to deal with SQLite. I am also new in Android, but I learned everything about SQLite from NotePad example.
Vector<String> vecInt = new Vector<String>; // you can use any datatype <int><float>
cursor.moveToFirst();
for(i=0;i<cursor.getCount();i++)
{
vecInt.add(cursor.getString(COLUMN_NUM));// if you are using datatype other then string then need to convert here
}
int [] val = new int[cursor.getCount()]; // integer array
for(int i= 0; i<cursor.getCount(); i++)
val[i] = cursor.getInt(cursor.getColumnIndex(COLUMN_NAME));