Strange behaviour retrieving values from a cursor query - android

Good day, Hope the tilte is not misleading. please take a look at the code snippet below and notice the commented parts:
//if(cursor.moveToFirst()){
if(cursor.moveToNext() == true){
// do {
Log.d(TAG, "Column Name in bindview is " + columnName);
String name = cursor.getString(cursor.getColumnIndexOrThrow(columnName));
Log.d(TAG, " name is " + name);
// } while(cursor.moveToNext());
//}
}
now only when i use cursor.moveToNext() do i get a value for the string "name".if i use the do/while statement as commented out in the above code or cursor.moveTofirst(), i get null value for the string. any idea why this is happening.
*Background:* am calling/initalizing this CursorAdapter from onLoadFinished() of a CursorLoader.

Perhaps you are trying to do this:
// Get the column's index
int index = cursor.getColumnIndex(columnName);
String name;
// You might want to check if the column exist with:
// if(index == -1)
// return;
// If you have move the Cursor's index, reset it:
// cursor.moveToFirst();
while(cursor.moveToNext()) { // == true is implied
name = cursor.getString(index);
Log.d(TAG, " name is " + name);
}
First find the column index outside the loop, the column index will not change unless you change the cursor. Then loop through all the valid results.

Related

How to check data in SQLite if already exist update or else insert in android

I want to check the data in SQLite if already exist can update or else insert.I am checking code like this what i mentioned below.
Code:
public long addmenus(String navigationdrawer,String optionname)
{
SQLiteDatabase menus=this.getWritableDatabase();
try {
ContentValues values=new ContentValues();
values.put(HEADER_NAME,navigationdrawer);
values.put(CHILD_NAME,optionname);
// menus.insert(TABLE_NAME,null,values);
// String owner=optionname;
Cursor cursor = menus.rawQuery("select * from TABLE_NAME where CHILD_NAME ='"+ optionname +"'", null);
if(cursor.getCount()<1)
{
//execute insert query here
long rows = menus.insert(TABLE_NAME, null, values);
return rows;
// return rows inserted.
}
else
{
//Perform the update query
String strFilter = "CHILD_NAME" + optionname;
long updaterow=menus.update(TABLE_NAME,values,strFilter,null);
return updaterow;
// return rows updated.
}
// menus.close();
} catch (Exception e) {
return -1;
}
finally {
if (menus != null)
menus.close();
}
}
My activity:
I converted whole json data into string object then insert into SQLite.
String productpage=jsonObject.toString();
db.addmenus(productpage,"Navigationmenus");
But It doesn't work.It couldn't insert into sqlite.
Anyone solve this problem Glad to appreciate.
Thanks in advance
You can user insertWithOnConflict() like this
db.insertWithOnConflict(TABLE, null, yourContentValues, SQLiteDatabase.CONFLICT_REPLACE);
You can use refer this Link. That link explains how to find the email address available in a table or not, you can change the column name, table and pass the values according. In your scenario you want to check the whether the name exists already or not, so you must pass which name you want to find. If the name is there then this method will return true or false. You can validate whether you had to insert or update according the response.i.e., false means you had to insert, otherwise if it is true means then you had to update.
you should use replace into
REPLACE INTO table(...) VALUES(...);
Question is not much clear but, i think you want to check either data/record is inserted in SQLite or not. you will need to define some extra variable long rowInserted insert() method returns the row ID of the newly inserted row, or -1 when an error occurred.
menus.insert(TABLE_NAME, null, values);
long rowInserted = db.insert(AddNewPhysicalPerson, null, newValues);
if(rowInserted != -1)
Toast.makeText(myContext, "New row added :" + rowInserted, Toast.LENGTH_SHORT).show();
else
Toast.makeText(myContext, "Something wrong", Toast.LENGTH_SHORT).show();
Updated
check either data is in table or column? for this you use this code
public boolean Exists(String id){
Cursor res = getAllData();
int count=0;
while (res.moveToNext()){
String email =res.getString(3);
if(email.equals(id)){
count++;
}
}
if(count==0){
return false;
} else{
return true;
}
}
Second you asking about json first store all data in any List run time and get string from it then you are able to store in SQlite
try {
items = jsonObject.getJSONArray("myjsonattribute");
List<MyAnySetterGetter> mList = new ArrayList<MyAnySetterGetter>();
for (int i = 0; i < items.length(); i++) {
JSONObject c = items.getJSONObject(i);
String mfilename = c.getString("myjsonattribute2");
mList.add(mfilename);
}
} catch (JSONException e) {
//e.printStackTrace();
}
then use above list to insert data from list to SQLite
like
String str1 = mList.get(position).getMYITEM1();
String str2 = mList.get(position).getMYITEM2();
insert str1 and str2 in SQLite hope you will get idea.
you should
set key for the table, then
insert(if the key existed it will not insert anymore), then
update all row.

How to use WHERE IN clause in Android Sqlite?

I am trying to execute an single update query where i have to update a single field for many persons.
Now the below query works :-
UPDATE PERSON SET ISSELECTED=1 WHERE ID IN (132,142,115,141,41,133,40,56,139,134,135,65,143,9,64,39,120,104,122,35,19,98,124,127,130,136,119,123,55,102,5,128,140,95,138,131,96,93,129,103,94,89,126,21,29,125,3,101,92,113,4,88,111,63,60,38,114,90,31,118,99,121,117,100,112,97,25,116,10,32,27,30,14,26,12,61,57,20,107,110,91,109,108,106,105,16,62,33,59,18,58,36,11,15,37,28,24,6,7,8,34,13)
But it does not return the number of updated rows when used with execSql or rawQuery
I am trying to form this query using the update method which returns the no. of rows affected
int rowsUpdatedSelected = db.update("PERSON", values, "ID" + " = ?", new String[] {id.toString()});
// where id is a StringBuilder object containing the ids like above
But this is not working.
You can write a method to make IN query string and use that as you selectionArgs. Like below
selectionArgs = idArray; // Where id array will be String[] and will contain all of your ids
selection = "ID" + makeInQueryString(idArray.length);
Where makeInQueryString() is
/**
* Creates where string which can be used for IN query. It creates string
* containing "?" separated by ",". This method can be used as below <br>
* ColumnName + makeInQueryString(size) <br>
* This will create IN query for provided column name.
*
* #param size
* size of the items
* #return IN query string of the form (?,?,?,?)
*/
public static String makeInQueryString(int size) {
StringBuilder sb = new StringBuilder();
if (size > 0) {
sb.append(" IN ( ");
String placeHolder = "";
for (int i = 0; i < size; i++) {
sb.append(placeHolder);
sb.append("?");
placeHolder = ",";
}
sb.append(" )");
}
return sb.toString();
}
Try this code.
Put single quote on your in you IN data
UPDATE PERSON SET ISSELECTED=1 WHERE ID IN ('132','142','115','14','1');
I didn't try this.. just give a try.. and let me know wethr its working or not..
int rowsUpdatedSelected = db.update("PERSON", values, "ID IN (?)", new String[] {id.toString()});
You can try using sqlite3_changes() for this:
This function returns the number of database rows that were changed or
inserted or deleted by the most recently completed SQL statement on
the database connection specified by the first parameter. Only changes
that are directly specified by the INSERT, UPDATE, or DELETE statement
are counted.
So after your update statement, add this code:
Cursor cursor = null;
try
{
cursor = db.rawQuery("SELECT changes() AS updated_row_count", null);
if(cursor != null && cursor.getCount() > 0 && cursor.moveToFirst())
{
final long count = cursor.getLong(0);
Log.d("LOG", "no. of updated rows : " + count);
}
} catch(SQLException e)
{
e.printStackTrace();
} finally
{
if(cursor != null)
{
cursor.close();
}
}
Hope this helps.

Make insert or update to SQLite taking care of empty table

The logic has to decide whether it will insert or update the table and yet it has to check if the table is not empty since.
So the current version of the code looks like this
if ((new XYZController(mContext)).getCount() == 0) {
new XYZController(mContext).insert(object);
} else {
XYZObject obj = (new XYZController(mContext)).getByString(string);
if (obj == null) {
new XYZController(mContext).insert(object);
} else {
new XYZController(mContext).update(object);
}
}
Since I cannot do WHERE query on empty SQLite table, I have to make additional "if empty" check.
Is there a way to omit such flow and just do 1 insert and 1 update caring if the table is empty or not?
PS. If we try to make a WHERE query on empty table, the app will break on the cursor.getString()
public XYZModel getByString(String s) {
String selectQuery = "SELECT * FROM " + TABLE_XYZ
+ " WHERE " + COLUMN + "='" + s + "'";
Cursor cursor = getRow(selectQuery);
XYZModel walk = null;
if (cursor != null) {
cursor.moveToFirst();
obj = new XYZModel(cursor.getString(1), cursor.getString(2),
cursor.getString(3));
}
if (obj == null)
obj = new XYZModel();
return obj;
}
Make sure your table has reasonable uniqueness constraints, such as a PRIMARY KEY or a UNIQUE constraint on some columns
Just use an insert with a conflict resolution algorithm such as replace, for example:
db.insertWithOnConflict(tableName, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE);
If the insert would violate a constraint, the conflicting rows are first deleted and then the new row is inserted. Therefore make sure you're providing a value for each column.
In case you have a database-generated INTEGER PRIMARY KEY, you can initially supply a NULL for its value (ContentValues.putNull()) and then capture the return value of the insert to get the generated primary key value.
This way you don't need the (incorrect) code that checks whether the row exists, nor do you need separate branches for inserts and updates.

Cursor Index Out of Bounds Exception: Index -1 requested with size 0

I am just trying to search for the data in multiple table.If the where condition data is not present in first table(tab1) then it has to search in the second table(tab2) but I am getting the exception showing that
Cursor Index Out of Bounds Exception: Index -1 requested with size 0
Here is my code
SQLiteDatabase db=openOrCreateDatabase("train",SQLiteDatabase.CREATE_IF_NECESSARY, null);
Cursor c1;
String[] table={"tab1","tab2","tab3","tab4"};
int i=0;
do {
c1 = db.rawQuery("select * from '"+table[i]+"' where name='Triplicane'", null);
i++;
} while(c1 == null);
int id1=c1.getInt(0);
String nam1=c1.getString(1);
Toast.makeText(fare.this,"ID no:"+id1, Toast.LENGTH_LONG).show();
Toast.makeText(fare.this,"name"+nam1, Toast.LENGTH_LONG).show();
So from the beginning. Implicitly, each Cursor is positioned before first row so if you want to work with it you need to call
cursor.moveToFirst()
that moves Cursor to first row if is not empty and then is ready for work. If Cursor is empty simply it returns false. So how i mentioned now this method is very handy indicator whether your Cursor is valid or not.
And as my recommendation i suggest you to change your code because i think is broken and it sounds like "spaghetti code"
Cursor c = null;
String[] tables = {"tab1", "tab2", "tab3", "tab4"};
for (String table: tables) {
String query = "select * from '" + table + "' where name = 'Triplicane'";
c = db.rawQuery(query, null);
if (c != null) {
if (c.moveToFirst()) { // if Cursor is not empty
int id = c.getInt(0);
String name = c.getString(1);
Toast.makeText(fare.this, "ID: " + id, Toast.LENGTH_LONG).show();
Toast.makeText(fare.this, "Name: " + name, Toast.LENGTH_LONG).show();
}
else {
// Cursor is empty
}
}
else {
// Cursor is null
}
}
Notes:
Now i want to tell you some suggestions:
An usage of parametrized statements is very good practise so in a
future if you will work with statements, use placeholders in them. Then your statements becomes more human-readable, safer(SQL Injection) and faster.
It's also a very good practise to create static final fields that will hold
your column names, table names etc. and to use
getColumnIndex(<columnName>) method to avoid "typo errors" which are looking for very bad.
Your Cursor flag to empty row , On Sqlite cursor pointed to row number -1 ,
then if you use c.moveNext() or c.moveToFirst() you'll be able to read rows "row by row "
write cursor.movetoFirst() before getting data from cursor.

Can't get sqlite to update properly on Android

I am trying to update my sqlite database in Android.
I have this function, adjustPosition, which should adjust the position column of my rows based on the position I pass in.
For example, if position=4 and I have two rows with positions 4,5 respectively, then they should be 3,4 by the time the function returns.
public void adjustPosition(int position){
while(true){
Cursor query = mDb.rawQuery("select _ID, position from icon where position = " + position, null);
if(query != null){
if(query.getCount()==0){
query.close();
return;
}
query.moveToFirst();
long id = query.getLong(0);
int newPosition = position-1;
String sqlQuery = "update icon set position=" + newPosition + " where _ID=" + id;
boolean result = mDb.rawQuery(sqlQuery, null) != null;
String sqlQuery2 = "select position from icon where _ID="+id;
query = mDb.rawQuery(sqlQuery2, null);
query.moveToFirst();
int posn = query.getInt(0); // should equal newPosition, which is 3
position++; // have a breakpoint here
query.close();
} else {
return;
}
}
}
I have a breakpoint at the line 'positon ++;' . The value of posn should be 3, but for some reason it is 4. I have tried the SQL query using the SQLite Manager plugin in Firefox and it works fine so I don't think my SQL syntax is the problem. Do I have to commit db changes or something?

Categories

Resources