Can't get sqlite to update properly on Android - 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?

Related

Android sql update or insert

I am trying to find the most efficient logic for the next situation.
I want to implement on my Android app storing in sql most used functions/actions by users.
dbase structure:
| _id | act_name (text unique) | counter (integer) |
code: (src https://stackoverflow.com/a/20568176/8006698)
int rowID = (int) db.insertWithOnConflict(TABLE_NAME, null, cv,SQLiteDatabase.CONFLICT_IGNORE);
if (rowID != -1){
myLog("Written to base with id = " + rowID);
} else {
db.execSQL("UPDATE stats SET counter=counter + 1 WHERE act_name = '" + mAction+"'");
myLog("stats updated");
}
I was surprised, that 'execSQL' doesn't return value as 'update' method.
I would use:
int rowID = db.update(...);
if (rowID == 0) {
//if not updated then insert
long insertedID = db.insert(...);
myLog("Inserted to base ");
} else
myLog("base updated");
but can't increase here count directly as 'counter=counter + 1' so I've to use 'insertWithOnConflict'.
I'm not sure, is it good practice to use it. Waiting for your ideas.
Replace this
db.execSQL("UPDATE stats SET counter=counter + 1 WHERE act_name = '" + mAction+"'");
Use this
ContentValues values=new ContentValues();
values.put("counter",1)
int rowCount=db.update("stats",values,"act_name=?",new String[]{mAction});
you get update count and do whatever you want.

sqlite app keeps crashing

So I'm trying to set up a basic database with clients that have 4 fields, id, firstname, lastname and age. I have one method that puts data in and one that logs it out to make sure it's working. Here is what I have:
Right at the beginning of the MainActivity class:
SQLiteDatabase clientsDatabase;
In my onCreate method:
try
{
clientsDatabase = this.openOrCreateDatabase("Clients", MODE_PRIVATE, null);
clientsDatabase.execSQL("CREATE TABLE IF NOT EXISTS clients (id INT(3), fName VARCHAR, lName VARCHAR, age INT(3))");
}
catch(Exception e)
{
e.printStackTrace();
}
And my method that puts new data in is:
public void addMember(int id, String f, String l, int a)
{
clientsDatabase.execSQL("INSERT INTO clients (id, fName, lName, age) VALUES (" + id + ", '" + f + "', '" + l + "', " + a + ")");
}
And my method that logs the data out based on the id you give to it is:
public void printMember(int id)
{
Cursor c = clientsDatabase.rawQuery("SELECT * FROM clients WHERE id = " + Integer.toString(id), null);
int idIndex = c.getColumnIndex("id");
int fNameIndex = c.getColumnIndex("fName");
int lNameIndex = c.getColumnIndex("lName");
int ageIndex = c.getColumnIndex("age");
c.moveToFirst();
while (c != null)
{
Log.i("Results - id", Integer.toString(c.getInt(idIndex)));
Log.i("Results - First name", c.getString(fNameIndex));
Log.i("Results - Last name", c.getString(lNameIndex));
Log.i("Results - Age", Integer.toString(c.getInt(ageIndex)));
c.moveToNext();
}
c.close();
}
And FINALLY! I set up a button with the 'onClick' method of:
public void logUser(View view)
{
addMember(1, "Clark", "Kent", 30);
printMember(1);
}
The emulator crashes when I press the button, and this is what shows up in the logs(It was A LOT, so I didn't wanna make this post any longer, so I put some screenshots):
http://imgur.com/a/LpDDd
The weird thing is IT IS logging the correct information. It just crashes afterward for some reason.
And I know this isn't the best way to do this, but I really need to get this way to work, so any help is appreciated
You should change your while loop to
while (!c.isAfterLast()) {
...
}
because c never gets null, it is just moved down and down until it's out of rows in the database.

Dynamic SQLite queries

I'm trying to implement dynamic queries in my Android app, to let the users search according to some criteria. In this case I'm trying to search simply by an integer value. Here's my attempt:
...
public String[][] listarNegocio(int idProyecto,
int minimo,
int maximo)
{
String[][] arrayDatos = null;
String[] parametros = {String.valueOf(idProyecto)};
Cursor cursor = null;
cursor = querySQL("SELECT *" +
" FROM negocio" +
" WHERE ? in (0, id_proyecto)", parametros);
if(cursor.getCount() > 0)
{
int i = minimo - 1;
arrayDatos = new String[maximo - minimo + 1][20];
while(cursor.moveToNext() && i < maximo)
{
// Here I fill the array with data
i = i + 1;
}
}
cursor.close();
CloseDB();
return(arrayDatos);
}
public Cursor querySQL(String sql, String[] selectionArgs)
{
Cursor oRet = null;
// Opens the database object in "write" mode.
db = oDB.getReadableDatabase();
oRet = db.rawQuery(sql, selectionArgs);
return(oRet);
}
...
I tested this query using SQLFiddle, and it should return only the rows where the column id_proyecto equals the parameter idProyecto, or every row if idProyecto equals 0. But it doesn't return anything. If I remove the WHERE clause and replace "parametros" with "null", it works fine.
Additionally, I need to search by text values, using LIKE. For example, WHERE col_name LIKE strName + '%' OR strName = ''. How should I format my parameters and the query to make it work?
You should do one query for each case. For an id that exists, do SELECT * FROM negocio WHERE id_proyecto = ?. For an id that doesn't exist (I'm assuming 0 isn't a real id), just query everything with SELECT * FROM negocio.
Code should be something like this:
if(parametros[0] != 0){
cursor = querySQL("SELECT *" +
" FROM negocio" +
" WHERE id_proyecto = ?", parametros);
} else {
cursor = querySQL("SELECT *" +
" FROM negocio", null);
}
Regarding your second question, it depends on what you're looking for, you could use LIKE '%param%' or CONTAINS for occurrences in between text, LIKE param for partial matches or just = param if you're looking an exact match.

Android database don't do anything if selected row doesn't exist

I made a query that requests a random row from database using ID. But I have a little problem. I want it to show a message if it exists or it doesn't exist. For example my database like that:
ID - ingilizce - turkce
1 - hello - merhaba
4 - hi - selam
As you see, the second and third record don't exist. I generate a random number between 1 and 4 and I get the row that belongs to ID. So, when it generates a number like 2 or 3, it will generate a new random number.
My code is here:
public void kelimeUret() {
SQLiteDatabase db = kelimeler.getReadableDatabase();
rastgele = new Random();
Cursor kayit = db.rawQuery("SELECT count(*) FROM kelimeler", null);
kayit.moveToFirst();
int max = Integer.parseInt(kayit.getString(0));
int min = 1;
int rastgeleKayit = rastgele.nextInt(max - min + 1) + min;
Cursor kayit3 = db.rawQuery("SELECT * FROM kelimeler WHERE id=" + rastgeleKayit, null);
kayit3.moveToFirst();
int kayitSayisi = kayit3.getCount();
if (kayitSayisi<1) {
//Toast.makeText(getApplicationContext(), "bu kayıt yok", Toast.LENGTH_SHORT).show();
//kelimeUret();
// I COULDN'T DO HERE !
} else {
Cursor kayit2 = db.rawQuery("SELECT ingilizce FROM kelimeler WHERE id=" + rastgeleKayit, null);
kayit2.moveToFirst();
String sonuc = kayit2.getString(0);
olusturulanKelime = sonuc;
kelime = (TextView) findViewById(R.id.kelime);
kelime.setText(sonuc);
}
Thanks for your responds...
Cursor kayit3 = db.rawQuery("SELECT * FROM kelimeler WHERE id=" + rastgeleKayit, null);
kayit3.moveToFirst();
kayit3.getCount(); will return the number of records returned by the query. If there are no records, then it does not exist. If it returns more than 1 record, then the record exist.
Hope this helps

Strange behaviour retrieving values from a cursor query

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.

Categories

Resources