Android SQLite error on cursor - java

I'm currently working on an android project and am stuck on this method. The cursor query works but anything after that does not. If I take out the 'returnCompany' method it runs so I'm guessing the error is inside the cursor query. The method is taking in a string parameter called 'companyNameParemeter'. FYI Android Studio is the text editor I'm using.
SQLiteDatabase db = this.getReadableDatabase();
String returnString = "";
Cursor cursor = db.rawQuery("Select * from " + CONTANT_INFO_AND_GPS_TABLE + " where " +
KEY_COMPANY_NAME + " = ? ", new String[] {companyNameParamater});
company returnCompany = new company(Integer.parseInt(cursor.getString(0)), cursor.getString(1),
cursor.getString(2), cursor.getString(3),Double.parseDouble(cursor.getString(4) ),
Double.parseDouble(cursor.getString(5)));
/* returnString = ("Company is:\t" + returnCompany.getCompanyName() + ",\nContact name:\t" +
returnCompany.getContactName() + ",\tContact No:\t" + returnCompany.getContactNumber()
+ ",\nGPS:\tLat:\t"
+ returnCompany.getGPS_Latitude() + "\tLong:\t" + returnCompany.getGPS_Longitude() );*/
return returnString;
I checked LogCat and the only relevant error I could find was this
04-04 12:06:38.237 2032-1714/? E/GCoreUlr: Received null location result

Try using
cursor.moveToFirst()
Right AFTER creating and filling it with db.rawquery or wichever call you use to get your data from your DB,
It will make sure your cursor is pointing at the first element you received, i may be wrong but i remember it's always pointing at the end of the data it contains when you fill it.

The error you show doesn't reflect the error you would typically get. However the code you have shown is clearly wrong and would result in an error because you are trying read a row when you are positioned at the start position of the cursor (aka beforeFirstRow).
You have to move to a row before you can get the data. As you only appear to have a single row, then using the Cursor method moveToFirst will either position you at the first (only) row. If the move cannot be made (no rows) then like all the Cursor move????? methods (moveTolast, moveToNext etc) a boolean false is returned (true if the move was made) hence it's use in within the if.
SQLiteDatabase db = this.getReadableDatabase();
String returnString = "";
Cursor cursor = db.rawQuery("Select * from " + CONTANT_INFO_AND_GPS_TABLE + " where " + KEY_COMPANY_NAME + " = ? ", new String[] {companyNameParamater});
if (cursor.moveToFirst()) { //<<<< Move the cursor to a row
company returnCompany = new company(Integer.parseInt(cursor.getString(0)),
cursor.getString(1),
cursor.getString(2),
cursor.getString(3),
Double.parseDouble(cursor.getString(4)),
Double.parseDouble(cursor.getString(5)));
/* returnString = ("Company is:\t" + returnCompany.getCompanyName() + ",\nContact name:\t" +
returnCompany.getContactName() + ",\tContact No:\t" +
returnCompany.getContactNumber()
+ ",\nGPS:\tLat:\t"
+ returnCompany.getGPS_Latitude() + "\tLong:\t" +
returnCompany.getGPS_Longitude() );
*/
}
return returnString;
P.S. Double.parseDouble(cursor.getString(4)) could be cursor.getDouble(4)

Related

delete item from local database function doesn't work

//the following function 'listens to the click' - here we are using an 'item click listener' which gives you a number of which one was clicked
lv_customerList.setOnItemClickListener((parent, view, position, id) -> {
//getting the customer that was just clicked to send it to the method to delete
//the parent of the listener is the listview
CustomerModel clickedCustomer = (CustomerModel) parent.getItemAtPosition(position); //this tells me which person was just clicked
//now we call the "deleteOne" function from the databaseHelper class
dataBaseHelper.deleteOne(clickedCustomer);
//now we update the list view
ShowCustomersOnListView(dataBaseHelper);
Toast.makeText(MainActivity.this, "Deleted" + clickedCustomer,Toast.LENGTH_SHORT).show();
});
This is the code in the MainActivity
//creating a new function that will delete contents from a database
public boolean deleteOne(CustomerModel customerModel) {
//find customerModel in the database. if is is found, delete it and return true, otherwise return false
SQLiteDatabase db = this.getWritableDatabase();
String queryString = "DELETE FROM" + CUSTOMER_TABLE + "WHERE" + CUSTOMER_ID + " = " + customerModel.getId();
Cursor cursor = db.rawQuery(queryString, null);
if (cursor.moveToFirst()) {
return true;
}
else {
return false;
}
}
And this is the code from the DatabaseHelper activity
I followed the https://youtu.be/312RhjfetP8 tutorial and copied the code exactly (although the android IDE suggested to change the...
new AdapterView.OnItemClickListener()
to a lambda (in the method in mainactivity)
But now whenever I click one of the rows (see video to understand what i mean) in the app - the app just crashes and I'm not sure why :(
Could someone please help me out?
Thank you so much!
I'm pretty sure that you miss a lot of space characters in the query String.
String queryString = "DELETE FROM" + CUSTOMER_TABLE + "WHERE" + CUSTOMER_ID + " = " + customerModel.getId();
should be changed to
String queryString = "DELETE FROM " + CUSTOMER_TABLE + " WHERE " + CUSTOMER_ID + " = " + customerModel.getId();
DeleteBuilder<CustomerModel, Integer> deletebuilder =
mcustomermodel.deleteBuilder();

Cannot get the max value in a SQLite database

I am trying to get the max id of a table in SQLite in Android. This is how I get it in the database helper:
public int getMaxIncrementation() {
SQLiteDatabase sqLiteDatabase = this.getReadableDatabase();
String result = "0";
try{
Cursor cursor = sqLiteDatabase.rawQuery("SELECT MAX(id) FROM " +TABLE_INCREMENTATION, new String[]{});
cursor.moveToFirst();
result = cursor.getString(cursor.getColumnIndex(INCREMENTATION_ID));
}catch (Exception ex) {
Log.e("ex", ex.getMessage());
}
return Integer.parseInt(result);
};
This is how I created the table:
private static final String CREATE_TABLE_INCREMENTATION = "CREATE TABLE IF NOT EXISTS " + TABLE_INCREMENTATION
+ "("
+ INCREMENTATION_DATEADDED + " TEXT,"
+ INCREMENTATION_DIRECTION + " INTEGER,"
+ INCREMENTATION_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ INCREMENTATION_USER + " TEXT"
+ ")";
This is the snapshot of my table with data in it:
On debugging, I always get this error:
Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor
is initialized correctly before accessing data from it.
First, since you don't have in the query any ? placeholders then you don't need to pass any parameters to the sql statement, so the 2nd argument of rawQuery() should be null.
Also you must give an alias to the column that your query returns and use it to get the returned value (you can't use INCREMENTATION_ID because it is not the name of the column returned):
Cursor cursor = sqLiteDatabase.rawQuery("SELECT MAX(id) AS maxid FROM " +TABLE_INCREMENTATION, null);
if (cursor.moveToFirst())
result = cursor.getString(cursor.getColumnIndex("maxid"));
Or if you don't use an alias then use 0 as there is only 1 column returned:
Cursor cursor = sqLiteDatabase.rawQuery("SELECT MAX(id) FROM " +TABLE_INCREMENTATION, null);
if (cursor.moveToFirst())
result = cursor.getString(0);

Storing data from an entire row, Android SQLite

So I have a method that allows me to get the id of a certain item by using a name i already have in an SQL Database. How would I go about getting the entire row of information and storing each item in its own variable.
Method that only works with ID
public Cursor getID(String name){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
String query = " SELECT " + COL1 + " FROM " + TABLE_NAME + " WHERE " + COL2 + " = '" + name + "'";
Cursor data = sqLiteDatabase.rawQuery(query, null);
return data;
}
And the method that gets the query and stores the result
Cursor data = mydb2.getID(name);
int itemId= -1;
while(data.moveToNext()){
itemId = data.getInt(0);
}
Using this method below how would i store all of the data in its own variable using this (or any other way to get data of entire row).
public Cursor rowData(String name){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
String query = " SELECT * FROM " + TABLE_NAME + " WHERE " + COL2 + " = '" + name + "'";
Cursor data = sqLiteDatabase.rawQuery(query, null);
return data;
}
I know this might be a dumb question, and I have tried looking at other questions, I have gotten this far I just don't know what to do next (I'm very new to Sq Lite databases and Android development)
You'd use something like :-
Cursor csr = instance_of_yourdbhelper.rowData();
while(csr.moveToNext()) {
long thisItemId = csr.getLong(csr.getColumnIndex(yourdbhelper.COL_1));
String thisName = csr.getString(csr.getColumnIndex(yourdbhelper.COL_2));
// etc for other columns
}
Notes
yourdbhelper is the class for your DatabaseHelper which is the class that extends SQLiteOpenHelper (the assumption is that the above methods are from such a class, as this is a common usage of SQLite)
instance_of_yourdbhelper is the instance of the DatabaseHelper class i.e. you may have yourdbhelper dbhlpr = new yourdbhelper(parameters);, in which case dbhlpr is the instance.
This just overwrites the same variables (thisItemId and thisName) for each row in the cursor, although there is perhaps the likliehood that the rowData method only returns one row.
You will likely encounter fewer errors using the getColumnIndex method as it returns the offset according to the column name. Miscalculated offsets is a frequent cause of problems.
You may wish to handle a no rows returned situation in which case you can use cursor.getCount(), which will return the number of rows in the cursor.

Android SQLite SELECT Query

I have taken String value from a EditText and set it inside SELECT QUERY after WHERE condition
As
TextView tv = (TextView) findViewById(R.id.textView3);
EditTextet2 et = (EditText) findViewById(R.id.editText1);
String name = et.getText().toString();
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = '"+name+"'", null);
c.moveToNext();
tv.setText(c.getString(c.getColumnIndex("email")));
But it doesn't work. Any suggestions?
Try trimming the string to make sure there is no extra white space:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE TRIM(name) = '"+name.trim()+"'", null);
Also use c.moveToFirst() like #thinksteep mentioned.
This is a complete code for select statements.
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT column1,column2,column3 FROM table ", null);
if (c.moveToFirst()){
do {
// Passing values
String column1 = c.getString(0);
String column2 = c.getString(1);
String column3 = c.getString(2);
// Do something Here with values
} while(c.moveToNext());
}
c.close();
db.close();
Try using the following statement:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = ?", new String[] {name});
Android requires that WHERE clauses compare to a ?, and you then specify an equal number of ? in the second parameter of the query (where you currently have null).
And as Nambari mentioned, you should use c.moveToFirst() rather than c.moveToNext()
Also, could there be quotations in name? That could screw things up as well.
Here is the below code.
String areaTyp = "SELECT " +AREA_TYPE + " FROM "
+ AREA_TYPE_TABLE + " where `" + TYPE + "`="
+ id;
where id is the condition on which result will be displayed.
public User searchUser(String name) {
User u = new User();
SQLiteDatabase db = this.getWritableDatabase(); //get the database that was created in this instance
Cursor c = db.rawQuery("select * from " + TABLE_NAME_User+" where username =?", new String[]{name});
if (c.moveToLast()) {
u.setUsername(c.getString(1));
u.setEmail(c.getString(1));
u.setImgUrl(c.getString(2));
u.setScoreEng(c.getString(3));
u.setScoreFr(c.getString(4));
u.setScoreSpan(c.getString(5));
u.setScoreGer(c.getString(6));
u.setLevelFr(c.getString(7));
u.setLevelEng(c.getString(8));
u.setLevelSpan(c.getString(9));
u.setLevelGer(c.getString(10));
return u;
}else {
Log.e("error not found", "user can't be found or database empty");
return u;
}
}
this is my code to select one user and one only
so you initiate an empty object of your class then
you call your writable Database
use a cursor in case there many and you need one
here you have a choice Use : 1-
if (c.moveToLast()) { } //it return the last element in that cursor
or Use : 2-
if(c.moveToFirst()) { } //return the first object in the cursor
and don't forget in case the database is empty you'll have to deal with that in my case i just return an empty object
Good Luck
Detailed answer:
String[] selectionArgs = new String[]{name};
Cursor c = db.rawQuery(
"SELECT * FROM " + tabl1 +
" WHERE " + name + " = ? ", selectionArgs
);
selectionArgs : this takes the 'name' you desire to compare with, as argrument.
Here note "A Cursor object, which is positioned before the first entry of the table you refer to".
So,to move to first entry :
c.moveToFirst();
getColumnIndex(String ColumnName) : this returns the zero-based column index for the given column name.
tv.setText(c.getString(c.getColumnIndex("email")));
In case, you want to go searching through multiple rows for a given name under 'name' column then use loop as below:
if (cursor.moveToFirst()){
do{
////go traversing through loops
}while(cursor.moveToNext());
}
This should solve the problem.

How To Test If Cursor Is Empty in a SQLiteDatabase Query

I have an SQL table which is created by the following code:
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + _ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + SUBJECT
+ " TEXT NOT NULL," + TOPIC + " TEXT NOT NULL, "
+ LECTURENUMBER + " TEXT NOT NULL, " + PAGENUMBER
+ " TEXT NOT NULL, " + DATE + " TEXT NOT NULL, " + _DATA
+ " TEXT NOT NULL);");
}
I query the table as follows:
String sql = "SELECT " + _ID + "," + SUBJECT + " FROM " + TABLE_NAME
+ " GROUP BY " + SUBJECT + ";";
Cursor cursor = subjects.getReadableDatabase().rawQuery(sql, null);
The problem is I have to start an Activity A if the cursor is empty(i.e. the table is storing no values) and Activity B if the cursor is not empty(i.e. table is filled).
I am unable to find a method which can tell me if the table is empty or not.
I Have tried to used Log as follows:
private void showSubjectsOnList() {
String sql = "SELECT " + _ID + "," + SUBJECT + " FROM " + TABLE_NAME
+ " GROUP BY " + SUBJECT + ";";
Cursor cursor = subjects.getReadableDatabase().rawQuery(sql, null);
Log.d("Events",Integer.toString(cursor.getCount()));
if(cursor.isNull(0)!=false){
cursor.close();
subjects.close();
startActivity(new Intent(this,OpenScreen.class));
}
}
But the LOG shows 1, if the table is empty...and again 1, if table has 1 entry....it shows 2, if table has two entries and so on.
Can you suggest some method of solving my problem of starting different activities based on if cursor is empty or not.
What about testing the cursor like this, and then doing what you've said:
if(cursor!=null && cursor.getCount()>0)
getCount ()
Returns the numbers of rows in the cursor
http://developer.android.com/reference/android/database/Cursor.html#getCount()
The easiest and cleanest way to test for an empty cursor is the following code:
if ( cursor.moveToFirst() ) {
// start activity a
} else {
// start activity b
}
Per the docs, the method returns false if the cursor is empty:
http://developer.android.com/reference/android/database/Cursor.html#moveToFirst%28%29
public abstract boolean moveToFirst ()
Added in API level 1 Move the cursor to the first row.
This method will return false if the cursor is empty.
Returns whether the move succeeded.
You just need to use getCount().
If your sql is correct but doesn't return any row you will have a NOT null cursor object but without a rows and getCount() will return 0.
Deleted records remain in SQLite as null records, but getCount() counts only not null records. If your table has some records that are null, some of not null records will have _Id numbers bigger than result of getCount(). To reach them, you can iterate cursor ( using for() loop ) double the number of times than result of getCount() and use the cursor to fill record_Id numbers into an array. Lets say resulting array is { 1, 2, 5, 6, 7, 8, 9, 11, 12, 14 }.
That means records 3, 4, 10, 13, are null records and your table has 14 record all together, not 10 that you got from getCount().
Remember:
getCount() returns number of not null records ,
cursor returns _Id numbers of not null records,
_Id numbers "missed" by cursor are _Id numbers of null records,
must reach sufficiently further than getCount() to get them all.
My suggestion would be using a ListActivity.
Those are Activity's which are meant to display items in a ListView. You can simply use a SimpleCursorAdapter to populate them (also illustrated in the ListActivitys JavaDoc page).
They also offer a setEmptyView()-method, which can be used to display a View (might be a TextView) which informs the user that there are no records yet and how he can create one.
An example on how to do that can be found here.
I believe your problem is you're not creating a proper query.
You should use the SQLiteDatabase query.
Cursor c = db.query(TABLE_NAME, null,
null, null, null, null, null);
You then can use c.getCount() to determine if the table has anything.

Categories

Resources