I'm trying to do a query with in a query
id = mCursor.getInt(mCursor.getColumnIndex(DatabaseHelper.COLUMN_SUBJECT_ID));
S = new Subject(id, getSubjectDescById(id));
Subjects.add(S);
the getSubjectDescById() function opens up another cursor on its own.
mCursor is opened before the code and closed after it.
Is it risky to have nested Cursors? If so what would be a better alternative to my code
I have not tested this though but i think,Yes you can use Nested cursors
Scenario:
Step-1> Open CURSOR-1
Step-2> Open CURSOR-2 and Use that cursor as a pointer for the new Cursor you care going to create
Step-3> Close CURSOR-2
Step-4> Close Cursor-1
Try this Sample::
private void DemoFunction() throws Exception {
DatabaseHandler mHelper;
SQLiteDatabase db = null;
Cursor mCursor1 = null;
Cursor mCursor2 = null;
try {
mHelper = new DatabaseHandler(getActivity());
db = mHelper.getReadableDatabase();
//make query for buffet-type
mCursor1 = db.rawQuery("<------My First Query ------>", null);
if(mCursor1.moveToFirst()){
do{
mCursor2 = db.rawQuery("<------My Second Query ------>", null);
if(mCursor2.moveToFirst()){
do{
}while(mCursor2.moveToNext());
Log.d("", "");
}
}while(mCursor1.moveToNext());
Log.d("", "");
}
} catch (Exception e) {
if(isErr==false){
errMsg=e.getLocalizedMessage();
isErr=true;
}
throw e;
}finally{
if(db!=null){
if(db.isOpen()) db.close();
}
if(mCursor1!=null||mCursor2!=null){
if(!mCursor2.isClosed())mCursor2.close();
if(!mCursor1.isClosed())mCursor1.close();
}
}
}
Note:- Make sure you close all the cursors
Related
I have an android sqlite database in Farsi (Persian) language, and I use the data in that for fill the ListView, but my problem is that I use item name in ListView in my query. For example, I get a name of ListView's text and use it in my query, but some of them does not show me correct answer from DB. I use the Farsi class for queries.
Here is my code:
List<String> getSubjects(String db_name, String name) {
List<String> collection = new ArrayList<String>();
Cursor cursor;
SQLiteDatabase db;
MyDataBaseHelper myDbHelper;
myDbHelper = new MyDataBaseHelper(this, db_name);
try {
cursor = null;
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
myDbHelper.openDataBase();
db = myDbHelper.getReadableDatabase();
cursor = db.rawQuery(
"select distinct type from mydata where group like '%"
+ farsi.ConvertBackToRealFarsi(name) + "%'", null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String uname = cursor.getString(cursor
.getColumnIndex("type"));
collection.add(DariGlyphUtils.reshapeText(uname));
} while (cursor.moveToNext());
}
}
} catch (SQLException sqle) {
throw sqle;
}
db.close();
return collection;
}
I'm trying to load an sqlite table as an arraylist so that i can use the data in it. I'm not too sure about the sqlite queries but i already have a class built to manipulate the strings as is, which is what i'm more comfortable with. I can load an individual row but i'm not sure how to get the whole table as an arraylist.
I have the following method in my main method
public void ShowCNData()
{
TestAdapter mDbHelper = new TestAdapter(this);
mDbHelper.createDatabase();
mDbHelper.open();
String allData = mDbHelper.getCYData().get(1)[1];
thing.setText(allData);
mDbHelper.close();
}
and the following method in my dbAdapter/Helper class
public ArrayList<String[]> getCYData()
{
ArrayList<String[]> CYData = new ArrayList<String[]>();
try
{
String sql ="SELECT * FROM cnYears ";
Cursor mCur = null;
do
{
mCur = mDb.rawQuery(sql, null);
CYData.add(new String[] {mCur.getString(0),mCur.getString(1),mCur.getString(2),mCur.getString(3),mCur.getString(4)});
}
while (mCur.moveToNext());
return CYData;
}
catch (SQLException mSQLException)
{
Log.e(TAG, "getTestData >>"+ mSQLException.toString());
throw mSQLException;
}
}
How do i load the data into my ArrayList?
Without actual log information, I'd guess your NullPointerException occurs when you get an empty cursor. Try it this way:
//initialize arraylist, execute query etc.
if (cursor.moveToFirst()) {
do {
String[] entry = new String[dataSize];
//pull your data here
data[0] = cursor.getInt(0);
data[1] = cursor.getString(1);
//...
list.add(entry);
} while (cursor.moveToNext());
}
// return arraylist
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android error - close() was never explicitly called on database
I have a problem in my android app.
I have a singleton implemented which has a method with the following code:
public Cursor getFooCursor(Context context)
{
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");
return c;
}
when i use this, i sometimes get the error: SQLiteDatabase: close() was never explicitly called on database
how to avoid this? the problem is, i can not simply make a db.close() befor i return c, because then its empty.
The approach I use is to pass an instance of the db to a class that returns the cursor:
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();
public Cursor getFooCursor(Context context, SQLiteDatabase db ) {
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null,
null, "Test DESC");
return c;
}
db.close();
Clients should open the database, then use this method to fetch the cursor, then close both the cursor and the database when they are finished. I would recommend not using a singleton here. Instead do something like this:
public class FooDB
{
private SQLiteDatabase db = null;
private void open() throws SQLiteException
{
if (db != null)
{
throw new SQLiteException("Database already opened");
}
// Create our open helper
StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
try
{
// Try to actually get the database objects
db = m_openHelper.getWritableDatabase();
}
catch (Exception e)
{
e.printStackTrace();
}
if (db == null)
{
throw new SQLiteException("Failed to open database");
}
}
private void close() throws SQLiteException
{
if (db != null)
{
db.close();
db = null;
}
}
public Cursor getFooCursor(Context context)
{
if(db == null)
throw new SQLiteException("Database not open");
Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");
return c;
}
}
I have a function which is supposed to add a new record to the SQLite database. This function will then call a function to return an int to a variable, then the rest of the code is skipped and it goes straight into the finally statement.
Below is the method.
SQLiteDatabase myDb = null;
if (type.equals("Website"))
{
details = formatUrl(details);
}
try
{
myDb = context.openOrCreateDatabase("PasswordManager", Context.MODE_PRIVATE, null);
int rowId = common.getNextID("password");
//ALL OF THIS CODE IS SKIPPED
ContentValues cv = new ContentValues();
cv.put("id", rowId);
cv.put("category", category);
cv.put("company", Encryption.encrypt(company));
cv.put("loginAction", Encryption.encrypt(details));
cv.put("username", Encryption.encrypt(username));
cv.put("password", Encryption.encrypt(password));
cv.put("type", type);
cv.put("appName", "N/A");
myDb.insert("password", null, cv);
}
catch (SQLiteException ex)
{
common.showBasicAlertDialog("Something has gone wrong.\n\nWe will fix this as soon as we can", false);
Log.e("Database Errror", ex.toString());
return false;
}
catch (SQLException ex)
{
common.showBasicAlertDialog("Something has gone wrong.\n\nWe will fix this as soon as we can", false);
Log.e("SQL Error", ex.toString());
return false;
}
finally
{
//IT GOES STRAIGHT INTO THIS CODE AFTER THE GETNEXTID METHOD RETURNS
if (myDb.isOpen())
{
myDb.close();
return true;
}
}
return false;
Below is the code for the getNextId() function
public int getNextID(String table)
{
int nextID = 1;
Cursor cursor = null;
SQLiteDatabase myDB = null;
try
{
myDB = context.openOrCreateDatabase("PasswordManager", Context.MODE_PRIVATE, null);
cursor = myDB.rawQuery("SELECT id FROM "+table+" ORDER BY id DESC LIMIT 1", null);
if (cursor != null)
{
cursor.moveToFirst();
nextID = cursor.getInt(0) + 1;
}
}
catch (SQLiteException ex)
{
Log.d("GetNextID", ex.toString());
nextID = -1;
}
finally
{
if (myDB.isOpen())
{
myDB.close();
}
if (!cursor.isClosed())
{
cursor.close();
}
}
return nextID;
}
I don't understand the content values have been skipped and it goes straight into the finally.
Perhaps some exception other than SQLException and SQLiteException have been thrown? If you put catch(Exception x) {...} you will probably see.
First try moving the line.
myDb = context.openOrCreateDatabase("PasswordManager", Context.MODE_PRIVATE, null);
below the line
int rowId = common.getNextID("password");
in your method. Or even better would be to add myDb as a parameter into your getNextID function so you are using the same DB reference and then don't close the DB in that function.
Add in the catch(Exception x) to your exceptions.
And then finally put a breakpoint inside your getNextID method and find out exactly which line it is breaking on.
Cheers
I am new to android . I have an application working with SQLite DB.
I need to push values from database to an arraylist of type object.
The code i used is given here.
private ArrayList<objectname> objectList = new ArrayList<objectname>();
//function used to get values from database
public ArrayList<objectname> getResults() {
MyDb db = new MyDb(this); //my database helper file
db.open();
Cursor c = db.getAllValues(); //function to retrieve all values from a table- written in MyDb.java file
if (c.moveToFirst())
{
do {
String date = c.getString(c.getColumnIndex("date"));
try
{
ob = new objectname();
ob.setDate(c.getString(c.getColumnIndex("date")));// setDate function is written in Class file
objectList.add(ob);
}
catch (Exception e) {
Log.e(MY_DEBUG_TAG, "Error " + e.toString());
}
} while (c.moveToNext());
}
db.close();
return objectList;
}
This is not working correctly. Not shown any errors but i didn't get values in to the arraylist objectList
Please help me..Thanks in advance..
try this:
private ArrayList<objectname> objectList = getResults();
private ArrayList<objectname> getResults() {
MyDb db = new MyDb(this); //my database helper file
db.open();
ArrayList<objectname> resultList = new ArrayList<objectname>();
Cursor c = db.getAllValues(); //function to retrieve all values from a table- written in MyDb.java file
while (c.moveToNext())
{
String date = c.getString(c.getColumnIndex("date"));
try
{
ob = new objectname();
ob.setDate(date);// setDate function is written in Class file
resultList.add(ob);
}
catch (Exception e) {
Log.e(MY_DEBUG_TAG, "Error " + e.toString());
}
}
c.close();
db.close();
return resultList;
}
I had a similar issue with retrieving values from the db using cursors and displaying on screen.. The below solution works for me..
Cursor cur = db.getAllValues();
int index = c.getColumnIndex("date");
cur.moveToFirst();
while (cur.isAfterLast() == false) {
System.out.println(cur.getString(index)); // For debug purposes
String date = cur.getString(index);
try {
ob = new objectname();
ob.setDate(date);
resultList.add(ob);
} catch (Exception e) {
Log.e(MY_DEBUG_TAG, "Error " + e.toString());
}
cur.moveToNext();
}
cur.close();
Probably your query is drawing a blank and moveToFirst is returning false.
What about logging the value of c.getCount() before your if statement?