Quering SqlLite database where clause Android - android

Hi I am developing an android app.I am trying to query from the database. I need to fetch everything from the table TASK where dbDate = AlarmDate and dbdTime = AlarmTime.
c = db.rawQuery("SELECT * FROM TASK WHERE dbDate = '"+AlarmDate+"' AND dbTime= '"+Alarmtime+"'", null);
The problem is ,the cursor c is null.
I am not sure where I am going wrong in the query. Please Help.
Thanks!

Android has binding method to avoid sql inject. You can use the second parameter to provide the variables of SQL.
Cursor cur = db.rawQuery("SELECT * FROM TASK WHERE dbDate = ? AND dbTime = ? ", new String[]{AlarmDate, AlarmDate});

Going by your comment 'I have used db = openOrCreateDatabase("Globus", 0, null); where Globus is the db name', you are not using SQLite properly with android.
What you should be doing is creating class which extends SQLiteOpenHelper, then make sure you override the onCreate and onUpgrade methods, these are the methods where you create tables and make changes, it has been said a hundred times on here so I will provide a link to a tutorial: http://www.codeproject.com/Articles/119293/Using-SQLite-Database-with-Android
When you do database operations, on the class call getWritableDatabase (http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#getWritableDatabase())
I say call getWritableDatabase because that way you don't need to worry if you can write to it, a writable database is also readable. Just FYI. Ask away for more details.
This should be the process of reading (writing is the same, just use what method you want instead of query):
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.beginTransaction();//this should lock the tables you are reading
Cursor c = db.rawQuery("select 1 where 1=?", new String[]{"1"});
if(c.moveToFirst()){
do{
//Do what you want with the row
}while(c.moveToNext());
}
c.close();
db.setTransactionSuccessful();
db.endTransaction();
db.close();
Here is the source code of a database helper I wrote, maybe it will help, read through it, understand how it works. https://bitbucket.org/FabianCCook/dbhelper/src/af7a8eba8d1a3f139e4170bbef9f1a2d3fdf1b47/src/nz/smartlemon/DatabaseHelper/ApplicationDataDbHelper.java?at=master
And if you want to know the reason the open methods exist read through this code
(This class was made from the help of someone elses code)
https://bitbucket.org/FabianCCook/dbhelper/src/af7a8eba8d1a3f139e4170bbef9f1a2d3fdf1b47/src/nz/smartlemon/DatabaseHelper/SDCardSQLiteOpenHelper.java?at=master

SQLiteDatabase db = getReadableDatabase();
Cursor cur = db.rawQuery("SELECT * FROM TASK WHERE dbDate = '"+AlarmDate+"' AND dbTime = '"+AlarmTime+"'",new String [] {});
Make sure you have gotten a readable database for 'db' or it will return null everytime.
Also change the end of your raw query to new String [] {}
Hope this helps, this is what I use in my applications.

Related

Initialize SQLite Cursor before accessing data from it

I am trying to insert data into a SQLite DB once a notification is received via FCM. For debugging purpose I am also inserting a dummy data into my DB when SHow Token is clicked on the HomeScreen activity.
However am getting
"I am getting "Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it."
Link to my code: - GitHub
Can someone please go through my code and let me know where I am going wrong.
Note - I added below in HomeScreen.java,MyFirebaseMessagingService.java and NotificationDetails.java
private SQLiteDB dbHelper = new SQLiteDB(this);
since the suggested
private SQLiteDB dbHelper;
did not work for me
When I used above I kept on getting Nullpointer exception, so I figured since the SQLiteDB class constructor is accepting a context, so let me pass one, post which I did not get NullPointer Exception.
Now I did this without being fully aware of the concept on context which I have been trying to wrap my head around, but since am an extreme noob to android I am not able to grasp it just yet. I suspect it might have something to do with the context I am passing.
Can someone please help me here with detailed instructions on how to fix this issue, I have been through many other threads on this but was not able to fix hence after 5 hrs of going through multiple SO questions, I am posting this one.
Thanks in advance to everyone in the community for the help. :)
Edit
Upon suggestion by admins, I am including below snippet of my code.
Where I am calling the cursor
dbHelper.insertNotification("This is a notification");
//Check if the message contains data
Cursor rs = dbHelper.getAllNotifications();
rs.moveToFirst();
token_text.setText("Token: " +rs.getString((rs.getColumnIndex("NOTIFICATION_DETAILS"))));
Insert Notification Function in SQLiteDB.java
public boolean insertNotification(String notification){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(NOTIFICATION_DETAILS,notification);
db.insert(NOTIFICATION_TABLE_NAME,null,contentValues);
return true;
}
getAllNotifications function
public Cursor getAllNotifications() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery( "SELECT * FROM " + NOTIFICATION_TABLE_NAME, null );
return res;
}
Couldn't read row 0, col -1 from CursorWindow.
Is saying that you are attempting to get the column at offset -1 from row 0 (the first row). So you have provided an invalid offset (it cannot be an offset of -1, the offset must be 0 or greater and the maximum value will be 1 less than the number of columns in the Cursor).
The most likely cause, is that Cursor method getColumnIndex(the_column_name_as_a_string) will return -1 when the column passed to the method cannot be found in the Cursor. Noting that due to a bug column name is case sensitive.
As such your issue is that the Cursor does not contain a column name NOTIFICATION_DETAILS and as you have used * (all columns) then that column does not exist in the table.
By the looks of it you should be using the String variable NOTIFICATION_DETAILS so you probably need to use :-
token_text.setText("Token: " +rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS)))); //<<<<<<<<<< double quotation marks removed.
Additional
You should NEVER assume that moveToFirst (or any Cursor move???? method) actually does the move. You should ALWAYS check the returned value. It will be true if the move was successful otherwise it would be false.
Again note that the column name passed to the getColumnIndex method is case dependant.
As such you should use something like
:-
dbHelper.insertNotification("This is a notification");
//Check if the message contains data
Cursor rs = dbHelper.getAllNotifications();
if (rs.moveToFirst()) {
token_text.setText("Token: " +rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS))));
} else {
........ code here if anything need to be done if there are no rows extracted
}
Addition re comment :-
Cursor rs = dbHelper.getAllNotifications(); rs.moveToFirst(); do{ for
(int i = 0; i < rs.getColumnCount(); i++) {
notification_array.add(rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS))));
} }while (rs.moveToNext());
using the following is much simpler :-
Cursor rs = dbHelper.getAllNotifications();
while (rs.moveToNext()) {
notification_array.add(rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS))));
}

Android - Efficient way using the Database Cursor

I've implemented a sqlite database in my application and I'm using the Android Cursor. I've written a database class with e.g. the database name and the table and column names. Here I also have various methods, like the following:
public Cursor getCorrectQuestions(int topic) {
SQLiteDatabase db = getReadableDatabase();
Cursor questionCursor = db.rawQuery(
"Select * FROM Result, Question WHERE Result.qid = Question._id AND correct = 1 AND topic = " + topic,
null);
questionCursor.moveToFirst();
return questionCursor;
}
public Cursor getExamQuestions() {
SQLiteDatabase db = getReadableDatabase();
Cursor questionCursor = db.rawQuery("Select * FROM Question WHERE topic = 7", null);
questionCursor.moveToFirst();
return questionCursor;
}
public Cursor getAnswerItems(String id) {
SQLiteDatabase db = getReadableDatabase();
Cursor answerCursor = db.rawQuery(
"Select * FROM Answer, Question WHERE Question._id = " + id + " AND Question._id = Answer.qid", null);
answerCursor.moveToFirst();
return answerCursor;
}
public Cursor getUserResults(String qid) {
SQLiteDatabase db = getReadableDatabase();
Cursor userResultsCursor = db.rawQuery("SELECT result FROM Result, Answer WHERE Result.qid = " + qid, null);
userResultsCursor.moveToFirst();
return userResultsCursor;
}
In the QuizActivity which has 3 cursors (answerCursor, questionCursor, userResultCursor) I call these methods.
My question is: is it necessary to create a SQLiteDatabase Object in every method or is it possible to define this once in my database constructor? And do I need 3 different cursors in my activity or is there a better way to handle this?
Assuming the methods you have written are part of a SQLiteOpenHelper, you are not really creating 3 database objects. Only the first call to getReadableDatabase() actually creates a database object, and subsequent calls reuse the same object over again.
You also need to make a new Cursor for each query you perform, as they cannot be edited after creation. In this sense, there is no way to simplify what you have already done.
As far as improvements to your code, there are a few things you can look at:
Consider putting your database in a ContentProvider and accessing it via URI's. This will require more upfront work, but will make it much easier if you want to share your database with other apps or sync your data to a server in the future.
Leave the cursor in its default position (don't call moveToFirst()). That way when the caller receives the cursor, it can use the following code to start iterating cursor rows without performing any further checks:
while (cursor.moveToNext()) {
// extract data
}
This is because the cursor returned from a query is initially positioned before the first row of data, so if the cursor is empty then the code inside the while loop simply never executes at all.

Update Query not working in Android Sqlite

My Java code Update Data base Table
String qq="UPDATE ChallanItems SET Recieve ="+str+" WHERE ItemNo = "+code;
Log.d("Qry", qq);
myDbHelper.updatequery(qq);
updatequery method
public void updatequery(String qry)
{
Cursor c = myDataBase.rawQuery(qry, null);
Log.d("Up", ""+c.getCount());
}
When i updated Data base the count return 0 and table not updated
I am using this Also but not work
String qq="UPDATE ChallanItems SET Recieve ="+str+" WHERE ItemNo = "+"'"+code+"'";
Please Help Me how i can fix this problem
Thanks In Advance
Use execSQL() for such SQL and not rawQuery().
rawQuery() just compiles the SQL but does not run it. You'd need to call one of the move...() methods on the returned Cursor to execute a step of the compiled SQL program.
execSQL() both compiles and runs the SQL program.
There's also possibly a syntax problem with your literals - use parameters i.e. ? placeholders in SQL and String[] bind arguments to be safe.
To update sqlite query change
Cursor c = myDataBase.rawQuery(qry, null);
to this
myDataBase.execSQL(qry);
try to use this:
ContentValues values = new ContentValues();
values.put("Recieve", str);
db.update("ChallanItems", values2, "ItemNo = ?", new String[] { code });

Does cursor copy the result set?

For example, if i use following code to query some data from database.
Uri uri = Uri.parse("content://com.android.contacts/contacts?address_book_index_extras=true");
String selection = "LEFT OUTER JOIN (select raw_contact_id, data1 from data where mimetype_id = 5) AS phone_data ON(_id = phone_data.raw_contact_id)";
Cursor c = getContentResolver().query(Contacts.CONTENT_URI, null, selection, null, null);
What i want to ask is after the query method, does database copy its result set to cursor or just make cursor something like a pointer and point to the first line of result set and query for more data when we call `moveToNext'
thanks
Yes. It is a readonly copy of the DB.
From Android Developers:
This interface provides random read-write access to the result set returned by a database query. Cursor implementations are not required to be synchronized so code using a Cursor from multiple threads should perform its own synchronization when using the Cursor.

fetching value from database and displaying it in a TextView in android

How can fetch values form database and display it in a textview in android?
Good to see you've given it some thought and tried on your own.
http://developer.android.com/guide/topics/data/data-storage.html#db has some good info on using SQLite on Android
It's also used in the Notepad tutorial: http://developer.android.com/resources/tutorials/notepad/notepad-ex1.html
I personally learned by using part of the guide from the "Hello, Android" book. The source code is available at: http://www.pragprog.com/titles/eband3/source_code - the SQL example is the one called 'Eventsv1'
You need SQLiteOpenHelper class to fetch readable instance of SQLiteDatabase in android. Then using query method you can get Cursor object of you query.
Can you explain more about what you want to do?
Try this,
Cursor c = db.query(TABLE_NAME, columns, null, null, null, null, null);
Then write
if(c!=null) {
c.moveToFirst();
while(!c.isAfterLast()) {
String col1Value = c.getString(1);//here you get col1 value
String col2Value = c.getString(2);//here you get col2 value
c.moveToNext();
}
c.deactivate();
c.close();
}

Categories

Resources