The query below should have only returned the numbers 0 through 8. However, the result are 0 thru 87. and 88 thru 99 are not shown. The next numbers shown are 100 thru 799. 800 thru 999 are not shown. So I see a pattern here, and it is that if the first number is within the range specified it is returned.
public Cursor getList(String user) {
String zero = "0";
String query = ("SELECT * FROM flavors WHERE inventory >= "+zero+" AND inventory <= "+user);
return mDb.rawQuery(query, null);
How can I keep the expected results withing the query parameters?
Thanks for all your efforts.
EDIT
For anyone that are looking for an answer as I was. Here is the final working statement.
Thanks to #FAT I was able to learn more about the sql query process from the links that where provided. Googling is an art it seems. I changed my code to meet my needs as follows.
public Cursor getList(String user) {
String zero = "0";
String query = ("SELECT * FROM flavors WHERE inventory != '' AND (cast(inventory as real)) >= " + zero + " AND (cast(inventory as real)) <= " + user);
return mDb.rawQuery(query, null);
}
The "cast" was the key to getting the string to be used to compare the two numbers. I also learned that you can exclude all null items. By adding "!= '', only the items that had an entry where returned in accordance with the statement. This even works for decimal numbers such as 5.5 or .5 etc.
You can't compare String value using >= or <=. Try using int value instead of string. For this case your column inventory should be int type.
Try this:
public Cursor getList(int user) {
int zero = 0;
String query = ("SELECT * FROM flavors WHERE inventory >= " + zero + " AND inventory <= " + user);
return mDb.rawQuery(query, null);
}
You can use BETWEEN like the following:
SELECT * FROM flavors WHERE inventory BETWEEN X AND Y
Related
So what I am doing is:
There are songs, in a specific order.
I am storing a list of IDs of the songs so that I can fetch them later, in the same order.
I am storing the list of IDs inside the variable in, and this is how I am fetching them:
StringBuilder sb = new StringBuilder( in.length * 2 - 1 );
sb.append( "?" );
for ( int i = 1; i < in.length; i ++ )
{
sb.append( ",?" );
}
String strIn = sb.toString( );
songCursor = context.getContentResolver( ).query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, TRACK_COLUMNS,
MediaStore.MediaColumns._ID + " IN (" + strIn + ")", in, null );
Everything is working fine, the only problem is, the list is in a different order than as was stored. Here I can't use sort order since obviously the order in which I want is not specified. I want it to be in the order in which it was stored but I have no idea how I can do it.
Also this is the information given while hovering over the query, so that explains the reason, but I don't have a solution.
selectionArgs You may include ?s in selection, which will be replaced
by the values from selectionArgs, in the order that they appear in the
selection.
For example:
In the above picture, I am storing the ids of all the songs in the order in which they are.
But when I am retrieving them, the order is changed.
Following the example in this post, the code below builds a CASE expression for the sortOrder argument in the query() call, alongside the selection argument.
StringBuilder inStr = new StringBuilder(MediaStore.MediaColumns._ID)
.append(" IN (?");
StringBuilder orderStr = new StringBuilder("CASE ")
.append(MediaStore.MediaColumns._ID)
.append(" WHEN ")
.append(in[0])
.append(" THEN 0");
for (int i = 1; i < in.length; i++) {
inStr.append(",?");
orderStr.append(" WHEN ")
.append(in[i])
.append(" THEN ")
.append(i);
}
inStr.append(")");
orderStr.append(" END, ")
.append(MediaStore.MediaColumns._ID)
.append(" ASC");
Cursor songCursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
TRACK_COLUMNS,
inStr.toString(),
in,
orderStr.toString());
The CASE expression is essentially assigning an alias value to each ID to sort by, rather than sorting by the actual ID value. No matter what the first ID is in the selection, its alias value will be 0, the second will be 1, the third 2, etc. Ordering by these values ascendingly, the resulting Cursor will be in the order of the IDs passed in the selection.
Sorry, I'm new. I have a table and need to get the column ID of the first min value of the table. The table is organized so the values keep decreasing until they get to 0 and all subsequent values are equal to zero.
It is possible for none of the values to be zero in which case Id need the last ID. It is important that I only have one return ID because of how I'm implementing it. This is the code I tried first but I'm getting an error.
I did not try to add the exception of there being no 0s here because I thought it might be easier to add an If statement in the implementation of the method I use.
The error I get confuses me because It seems like I can't use FIRST when I thought I could, but here it is:
android.database.sqlite.SQLiteException: no such function: FIRST (code
1): , while compiling: SELECT FIRST (_id) FROM graph WHERE bac = 0;
My code:
public int getWhereZero(){
int zero = 0;
SQLiteDatabase db = getReadableDatabase();
String query = "SELECT FIRST (" + COLUMN_ID
+ ") FROM " + TABLE_GRAPH
+" WHERE " + COLUMN_BAC
+ " = 0;";
Cursor cursor = db.rawQuery(query, null);
if(cursor != null){
cursor.moveToFirst();
zero = cursor.getInt(cursor.getColumnIndex(COLUMN_ID));
cursor.close();
}
return zero;
}
SQLite doesn't have a FIRST() function. However, you can limit the number of rows returned to one using LIMIT, so sorting by the desired order will get the row you need:
SELECT column_id FROM graph ORDER BY bac LIMIT 1;
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.
I'm having some issues working with a CursorAdapter.
In bindView(), I retrieve data in this way:
final String id = c.getString(c.getColumnIndexOrThrow(MySQLiteHelper.PROF_CONTACTS_KEY_ID));
final String name = c.getString(c.getColumnIndexOrThrow(MySQLiteHelper.PROF_CONTACTS_KEY_NAME));
Right after this code, I call
Log.e("Log",id+" <=> "+name);
But, because of some weird problem, I got as a result an ID moved forward by 1.
This is the situation in the DB (pulling it from the emulator, and opening it with SQLite Manager):
And this is the output:
With bigger numbers (>9), IDs start to mess even more up: number 10 becomes number 1, number 13 becomes number 5, etc.
I wouldn't have a lot of problems, in fact the only thing not matching is the id, all other info correspond, but I have a details activity to which I pass the ID in order to show to the user the detailed info.
This is the piece of code where I apply the adapter:
mCursor = mDb.rawGet("SELECT * FROM "+MySQLiteHelper.PROF_CONTACTS_TB_NAME+" LEFT JOIN "+
MySQLiteHelper.EXAMS_TB_NAME+" ON "+
MySQLiteHelper.PROF_CONTACTS_TB_NAME+"."+MySQLiteHelper.PROF_CONTACTS_KEY_COD_ESAME+"="+
MySQLiteHelper.EXAMS_TB_NAME+"."+MySQLiteHelper.EXAMS_KEY_COD
+ " ORDER BY " + MySQLiteHelper.PROF_CONTACTS_TB_NAME+"."+MySQLiteHelper.PROF_CONTACTS_KEY_ID);
if (mCursor.getCount() == 0) {
// error stuff.
} else {
String[] columns = new String[] {};
int[] to = new int[] {};
mDataAdapter = new CursorAdapterProfContacts(getSherlockActivity(), R.layout.item_prof_contact, mCursor, columns, to, 0);
mLvContacts.setAdapter(mDataAdapter);
}
Move the cursor to the first row,after initial cursor like,
mCursor.moveToFirst()
Are you sure that you have _id correctly populated when you insert a value? You can extract the database if you use the emulator and open it with SQLiteManager plugin for Firefox. As well, instead of quering all with *, use the same projection column names as you use inside y our bindView(); something is not matching here
It was due to a collision name: _id can be referred both to EXAMS and PROF. SQLlite chose EXAMS instead of PROF.
mCursor = mDb.rawGet("SELECT *, "+
MySQLiteHelper.PROF_CONTACTS_TB_NAME+"."+MySQLiteHelper.PROF_CONTACTS_KEY_ID+" AS idProf "+
" FROM "+MySQLiteHelper.PROF_CONTACTS_TB_NAME+" LEFT JOIN "+
MySQLiteHelper.EXAMS_TB_NAME+" ON "+
MySQLiteHelper.PROF_CONTACTS_TB_NAME+"."+MySQLiteHelper.PROF_CONTACTS_KEY_COD_ESAME+"="+
MySQLiteHelper.EXAMS_TB_NAME+"."+MySQLiteHelper.EXAMS_KEY_COD +
" ORDER BY " + MySQLiteHelper.PROF_CONTACTS_TB_NAME+"."+MySQLiteHelper.PROF_CONTACTS_KEY_ID);
And finally
final Long id = c.getLong(c.getColumnIndexOrThrow("idProf"));
This made the trick.
Collision name errors should be thrown, as it is in SQL and MySQL.
I would like to know how to prevent duplicate inserts when doing an RPC call from an Android client connected to app engine. Below is my code and what I tried at the back-end but when I do this I get an "Internal Server Error".
public void createentity(userentity e) {
PersistenceManager pm = PMF.get().getPersistenceManager();
//to go through the records and and check for duplicates
Query q = pm.newQuery("select from" + userentity.class + "where Country=='" + e.getCCNumber() + "'");
List < userentity > s = (List < userentity > ) q.execute();
//if the size is equal to to null means there is no duplicate
if (s.size() == 0) {
//insert the value
try {
pm.makePersistent(e);
} finally {
pm.close();
}
}
}
A couple of potential issues I see. First you should also be checking that your list isn't null. If it's null, your attempt to access the size will result in a null pointer exception. Secondly, in your query string remove the double equals. You only need single equals there. And secondly, add a spaces at the end and beginnings of your string literals. You're creating an invalid string. For instance, "select from ". And lastly, you shouldn't need to wrap the e.getCCNumber() in string literals.
Query q = pm.newQuery("select from " + userentity.class + " where Country= " + e.getCCNumber());