In my sql.query, there are times when the cursoe should return a null value. For example in the below code, the cursor is seeking a username. If the User has a username, then the cursor will return it. If not then I assume it is null. My problem is that when a cursor does find a null value, then I get a crash with an "out of bounds" error. Basically means the cursor did not find anything.
public static String getUserName() {
int rowIncrement = 1;
Log.d(DATABASE, "Getting Username");
String[] usercolumns = new String[] { KEY_ROWID, KEY_NAME, KEY_PASSWORD };
Cursor c = myDatabase.query(USER_TABLE, usercolumns, KEY_ROWID + "="
+ rowIncrement, null, null, null, null);
if (c != null) {
c.moveToFirst();
String lUserName = c.getString(1);
Log.d("DATABASE", "Username = " + lUserName);
return lUserName;
}
return null;
}
What is wrong with this code that would cause a crash if the cursor does not find anything?
It seems because of c.moveToFirst() returns boolean. So you should change your code like this.
if (c != null && c.moveToFirst()) {
String lUserName = c.getString(1);
Log.d("DATABASE", "Username = " + lUserName);
return lUserName;
}
You can check this here http://developer.android.com/reference/android/database/Cursor.html
Related
I need to retrieve deleted contacts in android. Below is my code
String WHERE_MODIFIED = "( "+ ContactsContract.RawContacts.DELETED + "= 1 )";
Cursor c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI,
null,
WHERE_MODIFIED,
null,
null);
if (c.getCount() > 0) {
c.moveToFirst();
do{
String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.e(TAG,name);
}while (c.moveToNext());
}else {
Log.e(TAG,"cursor = null");
}
It works when I delete contact and fetch using above code but after sometime of deletion it returns null. How do I fix this?
Cursor cursor = createDeletedCursor(contactLastUpdatedTime);
private Cursor createDeletedCursor(long lastupdatedTime) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
return resolver.query(
ContactsContract.DeletedContacts.CONTENT_URI,
DELETED_PROJECTION,
String.format("%s >= %d", ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP, lastupdatedTime),
null,
ContactsContract.DeletedContacts.CONTACT_ID
);
}
I've spent some hours on trying to solve this but the only answer I get is that I can't select from a string? Is that so? How do I do it otherwise? Here's my code:
public String getHotness(String l) {
// TODO Auto-generated method stub
String[] columns = new String []{ KEY_ROWID, KEY_NAME, KEY_HOTNESS};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + l, null, null, null, null);
int iHotness = c.getColumnIndex(KEY_HOTNESS);
if (c != null){
c.moveToFirst();
String hotness = c.getString(iHotness);
return hotness;
}
return null;
}
Where l is a name of a person in my database. How would I select and get information from this person by his name?
Thanks! You guys are the best!
You can select only records that fit a specific criteria using the WHERE clause for the select. In case of SQLiteDatabase#query() method, you need to use the third parameter.
Other considerations:
You should use parameters instead of concatenating the values to avoid common issues (like SQL injections).
No need to check if returned Cursor is null, it never is (as the documentation also states).
Also you should close your Cursor before returning from the method.
Example:
final String theName = "The person name";
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE, columns, KEY_NAME + " = ?", new String[]{theName}, null, null, null);
if (c.moveToNext()) {
// Do your stuff
}
} finally {
if (c != null) {
c.close();
}
}`
Note that previous query will only match rows where KEY_NAME column is exactly theName value. If you want to search by names that include theName value, you need to use LIKE operator instead.
final String likeName = "%" + theName + "%";
final Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_NAME + " LIKE ?", new String[]{likeName}, null, null, null);
LIKE is what you are looking for. % means anything BEFORE yourname is matching. ?yourname means only 1 char before. if you make sure that the name matches exactly you will need to use name = 'yourname' instead.
Cursor c = null;
try {
c = ourDatabase.rawQuery("SELECT * from yourtable where name LIKE '%yourname%', null);
if (c != null && c.getCount() > 0 && c.moveToFirst()) {
do {
c.getString(....);
} while (c.moveToNext());
}
} catch (Exception e) { e.printStackTrace(); }
finally {
if (c != null) c.close();
}
is there any thing wrong with this code, i want to query for data by using barcode and it show me that Cursor Index out of Bound exception .
public String getIdByBarcode(String ss) throws SQLException{
String[] column = new String[]{Pro_ID,Pro_Barcode, Pro_Name,Pro_NameKhmer, Pro_Quantity, Pro_Price, Pro_Description, Pro_Date};
Cursor c = ourDatabase.query(TABLE_NAME, column, Pro_Barcode + "= '" + ss + "' " , null, null, null, null);
if(c != null){
c.moveToFirst();
String id = c.getString(0);
Log.v(id, id + "Id" );
return id;
}
return null;
}
No results in the Cursor. You should check what moveToFirst() is returning (most likely false). Also you should use moveToNext(), not moveToFirst(). Also watch out that you're not checking ss parameter. This could lead to SQL injection vulnerabilities. You should be using parameters. Also I think you can use a single return in your method.
public String getIdByBarcode(String ss) throws SQLException {
String[] column = new String[]{Pro_ID,Pro_Barcode, Pro_Name,Pro_NameKhmer, Pro_Quantity, Pro_Price, Pro_Description, Pro_Date};
final String args = new String[1];
args[0] = ss;
Cursor c = ourDatabase.query(TABLE_NAME, column, Pro_Barcode + " = ?" , args, null, null, null);
String ret = null;
if(c.moveToNext()) {
ret = c.getString(0);
}
return ret;
}
The literature of moveToFirst() method:
public abstract boolean moveToFirst () Move the cursor to the first row. This method will return false if the cursor is empty.
Returns whether the move succeeded.
So your moveToFirst call is failing(because cusrsor has 0 elements) and that is the reason for crash.
Do this:
if(c != null && c.moveToFirst()) {
String id = c.getString(0);
Log.v(id, id + "Id" );
return id;
}
try this
String id;
if (c!= null && c.moveToNext){
String id = c.getString(0);
return id;
}
I am trying to get the first column like below sql but my code show error.
SELECT subject FROM setting WHERE rowid=1
public void getSetting(){
result = "";
SQLiteDatabase db = myDbHelper.getReadableDatabase();
Cursor c = db.query(true, "setting", new String[] {"subject", "language", "selection"}, "row=1", null, null, null, null, null);
for(c.moveToFirst();!(c.isAfterLast());c.moveToNext()){
result = result + c.getString(0);
result = result + c.getString(0);
result = result + c.getString(0);
}
if (c.getCount() == 0)
result = result + "result not found";
c.close();
db.close();
myDbHelper.close();
}
Your stuff is a little hard to understand, but i think i have an idea what you want. You what to get a cursor to return only one row where the row's id is a specific value. And you only want the string from one column of that returned row. I assume that the primary issue is your designation of the _id column that you're looking for. You either called it row or rowid, you gotta double-check that.
Moreover, i hope the following re-write clears up further issues that you might have.
public String getSetting() {
String result = "";
String[] columns = {"subject"};
String[] selectionArgs = {"1"};
String LIMIT = String.valueOf(1); // <-- number of results we want/expect
SQLiteDatabase db = myDbHelper.getReadableDatabase();
Cursor c = db.query(true, "setting", columns, "rowid = ?", selectionArgs, null, null, null, LIMIT);
if (c.moveToFirst()) {
result = result + c.getString(0);
} else {
result = result + "result not found";
}
c.close();
myDbHelper.close();
return result;
}
Moreover, moreover. If you get an error you should post it so that we have an idea what's going on.
I got this code in one of my methods. It should check if the string is already in the database and if it is the db entry gets updated. If it is not there I catch the exception and just create the entry.
String s="hallo";
try {
Cursor c1 = dba.fetchSubject(s);
dba.updateSubject(c1.getLong(c1.getColumnIndex(DbAdapter.KEY_ROWID)), s, t, r);
} catch (SQLException e){
dba.createSubject(s, t, r);
}
The problem is fetchSubject allway throws an Exception.
I use a similar method to get a db entry by a rowId instead of a String, which is working:
public Cursor fetchSubject(long rowId) throws SQLException {
Cursor mCursor = database.query(true, DATABASE_TABLE2, new String[] {
KEY_ROWID, KEY_SUBJECT, KEY_TEACHER, KEY_ROOM}, KEY_ROWID
+ "=" + rowId, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
The method called on top:
public Cursor fetchSubject(String subject) throws SQLException {
Cursor mCursor = database.query(true, DATABASE_TABLE2, new String[] {
KEY_ROWID, KEY_SUBJECT, KEY_TEACHER, KEY_ROOM}, KEY_SUBJECT
+ "=" + subject, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
The error:
sqlite returned: error code = 1, msg = no such column: hallo
I don't know where my error is. Isn't it possible to use a string at the selection parameter?
Try adding single quotes around hallo
String s = "'hallo'";
Essentially what you're doing is telling your query: select blah blah blah from TABLE where subject = hallo. Since hallo isn't surrounded by quotes, it is trying to find a variable / column with that name. When we surround it with quotes, we are saying that we are looking for the string within these quotes, rather than a variable.
Think of it like normal programming..
String s = hallo;
is completely different than
String s = "hallo";