Updating a single column is creating sqlite syntax error - android

I'm not sure what I'm doing wrong, but I'm trying to update a single integer value in a column of a table to 1 from 0. When creating the database, I set all values of the column to zero using:
for (int i = 0; i < setups.length; i++) {
ContentValues values = new ContentValues();
values.put(JokeDbContract.TblJoke.COLUMN_NAME_SETUP, setups[i]);
values.put(JokeDbContract.TblJoke.COLUMN_NAME_PUNCHLINE, punchlines[i]);
values.put(JokeDbContract.TblJoke.COLUMN_NAME_USED, 0);
db.insert(JokeDbContract.TblJoke.TABLE_NAME, null, values);
}
Then, in the actual activity, I'm doing:
private void findNewJoke() {
JokeDb jokeDb = JokeDb.getInstance(this);
SQLiteDatabase theDb = jokeDb.getDB();
String selection = JokeDbContract.TblJoke.COLUMN_NAME_USED + "=" + 0;
// Query database for a joke that has not been used, update the fields
// theJoke and thePunchline appropriately
String[] columns = {JokeDbContract.TblJoke._ID,
JokeDbContract.TblJoke.COLUMN_NAME_PUNCHLINE,
JokeDbContract.TblJoke.COLUMN_NAME_SETUP,
JokeDbContract.TblJoke.COLUMN_NAME_USED};
Cursor c = theDb.query(JokeDbContract.TblJoke.TABLE_NAME, columns, selection,
null, null, null, null);
if (c.moveToFirst() == false) {
Toast.makeText(this, R.string.error_retrieving_joke, Toast.LENGTH_LONG).show();
Log.e(getString(R.string.app_name),"No jokes retreived from DB in JokeActivity.findNewJoke()!");
}
else {
ContentValues values = new ContentValues();
theSetup = c.getString(c.getColumnIndexOrThrow(JokeDbContract.TblJoke.COLUMN_NAME_SETUP));
thePunchline = c.getString(c.getColumnIndexOrThrow(JokeDbContract.TblJoke.COLUMN_NAME_PUNCHLINE));
String updateSelection = JokeDbContract.TblJoke.COLUMN_NAME_SETUP + "=" + theSetup;
values.put(JokeDbContract.TblJoke.COLUMN_NAME_USED, 1);
theDb.update(JokeDbContract.TblJoke.TABLE_NAME, values, updateSelection, null);
}
}
I'm getting an error on the update:
java.lang.RuntimeException: .... while compiling: UPDATE jokes SET used=?
WHERE setup=Why do programmers always mix up Halloween and Christmas?
It seems as though I'm not getting an actual value set for the used column. What the program ultimately does is cycle through jokes where used=0, then sets used to 1 when it has been viewed. So the query only pulls those jokes that aren't used yet. I have a feeling I'm missing something simple, one can hope.

I think you are having problems with quotation marks.
Example:
String updateSelection = JokeDbContract.TblJoke.COLUMN_NAME_SETUP + "=\"" + theSetup + "\"";
However, the recommended way to do this, would be:
theDb.update(JokeDbContract.TblJoke.TABLE_NAME, values, JokeDbContract.TblJoke.COLUMN_NAME_SETUP + " = ?", new String[] { theSetup });
It is better to use field = ?, because this helps sqlite cache queries (I believe).

Related

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.

Query a Sqlite Database Using an Array Android

I have researched a handful of other forums with a similar topic and I have yet to find an answer to this frustrating issue. I am trying to use an array to check if a column in my database has one of the multiple values in the array. My cursor is as follows:
public Cursor notificationQuery(String geoIds) {
Log.e("STRINGS", geoIds);
return mDb.query(Constants.TABLE_POI_NAME,
new String[]{Constants.TABLE_COLUMN_ID, Constants.TABLE_COLUMN_POI_NAME,
Constants.TABLE_COLUMN_LATITUDE, Constants.TABLE_COLUMN_LONGITUDE,
Constants.TABLE_COLUMN_GEO_ID},
Constants.TABLE_COLUMN_GEO_ID + " IN (?)",
new String[]{geoIds},
null, null, null, null);
}
geoIds is currently an array of two values which has been converted into a string. The logged value of that string is below:
21007b0f-6b20-4eff-9a76-b412db8daa2e,26c695d6-6cb4-4c74-9933-281813a06fd9
Those are to separate Id values separated by a comma. When I test each one individually using "= ?" instead of "IN (?)" I get a proper match with the database and my cursor returns a value. However, when combined my cursor returns nothing when it should return two rows from the database. Please help me solve this issue! Thanks!
Consider a function String makePlaceholders(int len) which returns len question-marks separated with commas, then:
public Cursor notificationQuery(String geoId1,String geoId2) {
//assume we split this geoIds to 2 different values. you need to have 2 strings no 1
String[] ids = { geoId1, geoId2 }; // do whatever is needed first depends on your inputs
String query = "SELECT * FROM "+ Constants.TABLE_POI_NAME + " WHERE "+
Constants.TABLE_COLUMN_GEO_ID +" IN (" + makePlaceholders(names.length) + ")";
return mDb.rawQuery(query, ids); // ids is the table above
}
Here is one implementation of makePlaceholders(int len):
String makePlaceholders(int len) {
if (len < 1) {
// It will lead to an invalid query anyway ..
throw new RuntimeException("No placeholders");
} else {
StringBuilder sb = new StringBuilder(len * 2 - 1);
sb.append("?");
for (int i = 1; i < len; i++) {
sb.append(",?");
}
return sb.toString();
}
}
Or more simply, use the geoIds variable directly:
public Cursor notificationQuery(String geoIds) {
Log.e("STRINGS", geoIds);
return mDb.query(Constants.TABLE_POI_NAME,
new String[]{Constants.TABLE_COLUMN_ID, Constants.TABLE_COLUMN_POI_NAME,
Constants.TABLE_COLUMN_LATITUDE, Constants.TABLE_COLUMN_LONGITUDE,
Constants.TABLE_COLUMN_GEO_ID},
Constants.TABLE_COLUMN_GEO_ID + " IN (" + geoIds + ")",
null, null, null, null, null);
}
This approach is less secure but will likely give you the result you expect.

I can't get data from database using cursor

I have make following function for getting data.
public List<Presentation> getSlideMaster() {
List<Presentation> pptList = new ArrayList<Presentation>();
String selectQuery = "SELECT * FROM "
+ Constants.SLIDE_MASTER.slideMaster_Table + " WHERE dm_Id=" + lastDeckID;
SQLiteDatabase db = dbhelper.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
Presentation presentation = new Presentation();
presentation.setSlideId(cursor.getString(0));
getSlideID = presentation.getSlideId();
Log.i("string slide id in database helper", "" + presentation.getSlideId());
pptList.add(presentation);
} while (cursor.moveToNext());
}
String selectQuery2 = "SELECT sl_Id FROM "
+ Constants.SLIDE_LAYOUT.slideLayout_Table + " WHERE sm_Id = "
+ getSlideID;
Cursor cursorSL = db.rawQuery(selectQuery2, null);
Log.i("query", ""+selectQuery2);
if(cursorSL.moveToFirst()){
Log.i("getslideLayout function", "");
do{
Log.i("query string 0 ", ""+cursorSL.getString(0));
Presentation presentation = new Presentation();
presentation.setSlideLayoutId(cursorSL.getString(0));
getSlideLayoutId = presentation.getSlideLayoutId();
Log.i("string slide layout id in slideMaster", "" + getSlideLayoutId);
}while(cursorSL.moveToNext());
}
else{
Log.i("No Data Found!!!!!", "");
}
cursor.close();
cursorSL.close();
db.close();
return pptList;
}
I getting data from slideMaster_Table very fine and easily but I can't get data from another query, which is not print any value in Logcat inside of if(cursorSL.moveToFirst()) condition
When I use code in another activity i can get sl_Id very easily.
may below solution solve your problem
use Cursor cursorSL = db.rawQuery(selectQuery2, new String[]{getSlideID});
for
selectQuery2="SELECT sl_Id FROM "+Constants.SLIDE_LAYOUT.slideLayout_Table + " WHERE sm_Id = ?";
My speculation is that you have troubles constructing the second query. Basically it is never a good idea to construct database queries like you do. The android database API is providing more accurate interface for that. Rewrite your second part of program to:
String [] selectArgs = {getSlideID};
String selectQuery2 = "sm_Id = ?";
Cursor cursorSL = db.query(Constants.SLIDE_LAYOUT.slideLayout_Table, null,
selectQuery2, selectArgs, null, null, null, null);
Note that the fourth parameter of query is meant for substitution of where arguments, it is String[] and all the array members are substituted in sequence in the places of ? in the query string.
I think you might be facing problem with constructing the query.
PS: You are also misusing the log tags:
Log.i("No Data Found!!!!!", "");
Should actually be Log.i("TAG", "No Data Found!!!!!");
The first parameter is log tag and is supposed to be used for grouping related log messages, in your case you print every message in its own group, which does not make much sense.
I know this note will not solve your immediate problem, but I am pointing it out, so that you will know it for the future (I also suffer from seeing colleagues of mine learning from SO wrong practises like that one).

How to update the table values

I have the table(shown in fig). I want to update the time column. I have the medicine_id(second column) how to update the different times depend upon the same medicine_id(second column).
Also, I have four rows in my DB when I updated time it should be two row means, I want to remove the other two rows with the particular medicine_id..
I have the following code for update:
if(mon) {
for (int i = 0; i < dosage_per_day; i++) {
mMedicineDbHelper.updateMedicines(new
MedicineTime(row_id, time_InMillies[i]));
}
}
My DB code:
public void updateMedicines(MedicineTime medicineTime) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(ID, medicineTime.getId());
values.put(MEDICINEID, medicineTime.getMedicine_id());
values.put(TIME, medicineTime.getTime_in_millis());
db.update(TABLENAME, values, MEDICINEID + " = ?",
new String[]{String.valueOf(medicineTime.getMedicine_id())});
db.close();
}
It shows exception..
anybody help to solve this...
For the original question asked you're executing the following code:
db.update(TABLENAME, values, MEDICINEID + " = ?",
new String[]{String.valueOf(medicineTime.getMedicine_id())});
For some reason on Android, converting numeric values to Strings and using them for selection args never works properly. See: Android Sqlite selection args[] with int values. The best way to do this is the following:
db.update(TABLENAME, values, MEDICINEID + " = " + medicineTime.getMedicine_id(), null);

Android SqlLite update last inserted row

This is what i am using for insert:
public long insert(String content, Date startAt, Date endAt) {
if (content == null || startAt == null) {
return 0;
}
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_CONTENT, content);
contentValues.put(KEY_START_AT, startAt.getTime());
if (endAt == null) {
contentValues.putNull(KEY_END_AT);
} else {
contentValues.put(KEY_END_AT, endAt.getTime());
}
return sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
}
now i want to create update method which will update last inserted row. How can i get last inserted row?
If you have an id attribute that works as a primary key, you can do a raw database query on SqlLite.
Cursor cc = this.mDb.rawQuery("SELECT *" + " FROM " + "<Your DATABASE_NAME> " +
"ORDER BY id " + "DESC LIMIT 1", null);
return cc;
Here,
1. It returns a cursor.
2. mDb is a SQLiteDatabase class instance.
3. ORDER BY id allows the query to sort by id number. As I said, if you have an id as primary key in your table, your latest entry will have the maximum id number.
4. DESC allows to sort by descending order.
5. LIMIT 1 allows to return only 1 row.
6. Always be careful when writing raw queries, white spaces inside the query can be a lot of pain when you do not handle them carefully.
For further queries you can see this tutorial. And obviously Divya's answer is also a good one.
You can use a cursor to retrieve rows and say :
cursor.moveToLast();
OR
cursor.moveToPosition(cursor.getCount() - 1);
When you insert a row in to your table the insert query returns the key of the last inserted row. You can now use this key to update this row.
for example
int newInsertedKey = sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
update table_name set column_name = 'Change 2' where columnID = newInsertedKey
An efficient method would be to avoid anymore database queries to get the last updated row.
Maybe he should use something like this
public long getLastId() {
Cursor c = mDb.query(currentTableName, new String[] { "MAX(_id)" },
null, null, null, null, null, null);
try{
c.moveToFirst();
long id = c.getLong(0);
return id;
}catch(Exception e){
return 0;
}
}
where _id is column by which you identify rows

Categories

Resources