I'm calling a method to see if there is a value inside the database.
String[] columns ={table.NAME};
String[] selectionsArgs = {name};
Cursor cursor = db.query(table.TABLE_NAME, columns, table.NAME+"= ?", selectionsArgs,null, null, null, null);
int index = cursor.getColumnIndex(table.ID);
Irrespective of whether the name exists or not the index is always -1.
Why ?
Irrespective of whether the name exists or not the index is always -1. Why ?
Because you didn't include table.ID in columns.
getColumnIndex() can only find columns that are there in the cursor, irrespective of whether there are any rows.
Even without the table at hand, seems a lot like you are creating the query wrong.
Strange things I see:
Using table.NAME for the columns name.
Using table.NAME also for the WHERE clause condition
Having an extra space in that "= ?"
Try with:
Cursor cursor = db.query(table.TABLE_NAME ,null ,null ,null ,null, null, null, null);
Also, check this answer out for reference: SQLiteDatabase.query method
Related
If someone knows a better way to get a rowId from text in the row, please let me know.
I've been running around in circles with this and I know it's probably something simple, but I can't figure it out. Hoping someone can tell me what I'm doing wrong. I'm getting an error running this SQLite code:
String where = "SELECT rowid, * FROM masterRecord WHERE masNameCol=" + name;
Cursor c = db.query(true, masterName, ALL_KEYS_MASTER, where, null, null, null, null, null);
The error points to the second line.
"name" is a string variable (in this case it's "Mary"). The exact error I'm getting is:
SQLiteLog: (1) near "SELECT": syntax error in "SELECT DISTINCT _id, masNameCol, masTotalTimeCol FROM masterRecord WHERE SELECT rowid, * FROM masterRecord WHERE masNameCol=Mary"
I've tried every syntax change I could find and think of, and it never changes the error. I'm just trying to get the rowId of the row so I can change a value in another column.
Use rawQuery(), not query().
You are trying to specify the entire SQL statement, which is what rawQuery() is for. query() assembles the SQL statement from pieces, and your one piece (where) is not just the WHERE clause.
Use placeholders for queries:
where = "masNameCol = ?";
whereArgs = new String[] { name };
columns = new String[] { "rowId" , /* all other column names you are interested in */ };
Cursor c = db.query("mytable", columns, where, whereArgs, null, null, null);
My app is a dictionary and now I am working on making it available offline. The database is downloaded and now we have the situation that there is no internet. I need to use the local database. I get my readable database, and then set up a query. On my own testing phone everything works fine. But now before publishing the update I was trying it on two other phones, just to see that the ? in the selection are not replaced by the values in the selectionArgs.
The debugger just shows that the sql statement was built without replacing anything in the selection.
It works on my phone on Android 8.1, but with the two phone that are lower, it stops working and I am out of ideas.
I also tried changing it to db.rawQuery() but that ended with the same result.
String selection = "eng LIKE ? OR oky LIKE ? OR engpl LIKE ? OR okypl LIKE ? OR engcom LIKE ? OR okycom LIKE ? OR Alternative LIKE ?";
String[] selectionArgs = {term, term, term, term, com, com, term};
String orderBy = "eng, oky ASC";
Cursor cursor = db.query(DictionaryContract.WordEntry.TABLE_NAME, null, selection, selectionArgs, null, null, orderBy);
Now I expected the result to give me the terms that fit to the word (term) that was searched for by the user, but instead the cursor is empty, because there is no term containing a question mark.
Especially confusing is that it works on one phone and not on others.
The debugger won't show the resolved ?'s as the replacement of the ?'s is done by the underlying SDK (sqlite implementation) which is in C rather than java.
The best that you can see are the bindArgs e.g. for the following code :-
csr = mDBhlpr.getWritableDatabase().query("table1",null,"id=?",new String[]{"1"},null,null,null);
while (csr.moveToNext()) {
long id = csr.getLong(csr.getColumnIndex(DBHelper.COL_TABLE1_ID));
}
with a breakpoint at the 1st line then you could get :-
I don't believe that the issue is with the binding of the arguments, rather that it is elsewhere. You could test this by changing :-
Cursor cursor = db.query(DictionaryContract.WordEntry.TABLE_NAME, null, selection, selectionArgs, null, null, orderBy);
To
Cursor cursor = db.query(DictionaryContract.WordEntry.TABLE_NAME, null, null, null, null, null, null);
DatabaseUtils.dumpCursor(cursor);
i.e. select all rows, and them write all the rows in the Cursor to the Log.
If still none then the tables on the other devices are empty.
If an Exception occurs then you would have to investigate that.
If this works as expected, then progressively (one by one) add the selection criteria and args.
e.g. first would be
String selection = "eng LIKE ?";
String[] selectionArgs = {term};
String orderBy = "eng, oky ASC";
Cursor cursor = db.query(DictionaryContract.WordEntry.TABLE_NAME, null, selection, selectionArgs, null, null, null);
then :-
String selection = "eng LIKE ? OR oky LIKE ?";
String[] selectionArgs = {term, term};
String orderBy = "eng, oky ASC";
Cursor cursor = db.query(DictionaryContract.WordEntry.TABLE_NAME, null, selection, selectionArgs, null, null,null);
and so on (note finally re-add the order by).
If none of the above works, then your issue (as expected) is elsewhere.
I'm writing a method to update default settings in a table. The table is very simple: two columns, the first containing labels to indicate the type of setting, the second to store the value of the setting.
At this point in the execution, the table is empty. I'm just setting up the initial value. So, I expect that this cursor will come back empty. But instead, I'm getting an error (shown below). The setting that I am working with is called "lastPlayer" and is supposed to get stored in the "SETTING_COLUMN" in the "SETTINGS_TABLE". Here's the code:
public static void updateSetting(String setting, String newVal) {
String table = "SETTINGS_TABLE";
String[] resultColumn = new String[] {VALUE_COLUMN};
String where = SETTING_COLUMN + "=" + setting;
System.err.println(where);
SQLiteDatabase db = godSimDBOpenHelper.getWritableDatabase();
Cursor cursor = db.query(table, resultColumn, where, null, null, null, null);
System.err.println("cursor returned"); //I never see this ouput
\\more
}
sqlite returned: error code = 1, msg = no such column: lastPlayer
Why is it saying that there is no such column lastPlayer? I thought that I was telling the query to look at the column "SETTING_COLUMN" and return the record where that column has a value "lastPlayer". I'm confused. Can somebody straighten me out? I've been looking a this for an hour and I just don't see what I am doing wrong.
Thanks!
You're not properly building/escaping your query. Since the value lastPlayer is not in quotes, your statement is checking for equality of two columns, which is what that error message is saying.
To properly build your query, it's best to not do this manually with String concatenation. Instead, the parameter selectionArgs of SQLiteDatabase.query() is meant to do this.
The parameters in your query should be defined as ? and then filled in based on the selectionArgs. From the docs:
You may include ?s in selection, which will be replaced by the values
from selectionArgs, in order that they appear in the selection. The
values will be bound as Strings.
So, your code would look like this:
String where = SETTING_COLUMN + " = ?";
Cursor cursor = db.query(table, resultColumn, where, new String[] { setting }, null, null, null);
I have a one row database just for saving app data. My goal is to read one column (one value) from it.
This query returns all the columns in a Cursor:
public Cursor readAll() {
return getReadableDatabase().query(tableName, null, null, null, null, null, null);
}
It returns a Cursor with one row in it, just perfect. However, I don't want to read all columns at once, because it's slow as I have blob's in db too.
Instead, I'd like to read just one column at a time, separately. For example, for a column called "TEXT" it would be this:
public Cursor readText() {
String[] projection = new String[]{"TEXT"};
return getReadableDatabase().query(tableName, projection, null, null, null, null, null);
}
However, this won't work, as I get back a Cursor with zero rows.
So, how to read a specific column from SQLiteBatabase in Android?
public Cursor readText() {
return getReadableDatabase().rawQuery("SELECT colName FROM myTable", new String[] {});
}
Syntax seems to be correct. Check please that you use right name of the column. Showing the table generation code and actual query code could help.
You can use this one also
public Cursor readText() {
return getReadableDatabase().rawQuery("SELECT column_name FROM table_name", null);
}
I have a query that selects rows in a ListView without having a limit. But now that I have implemented a SharedPreferences that the user can select how much rows will be displayed in the ListView, my SQLite query doesn't work. I'm passing the argument this way:
return wDb.query(TABELANOME, new String[] {IDTIT, TAREFATIT, SUMARIOTIT}, CONCLUIDOTIT + "=1", null, null, null, null, "LIMIT='" + limite + "'");
The equals (=) operator is not used with the LIMIT clause. Remove it.
Here's an example LIMIT query:
SELECT column FROM table ORDER BY somethingelse LIMIT 5, 10
Or:
SELECT column FROM table ORDER BY somethingelse LIMIT 10
In your case, the correct statement would be:
return wDb.query(TABELANOME, new String[] {IDTIT, TAREFATIT, SUMARIOTIT}, CONCLUIDOTIT + "=1", null, null, null, null, String.valueOf(limite));
Take a look here at the SQLite select syntax: http://www.sqlite.org/syntaxdiagrams.html#select-stmt
This image is rather useful: http://www.sqlite.org/images/syntax/select-stmt.gif
For anyone stumbling across this answer looking for a way to use a LIMIT clause with an OFFSET, I found out from this bug that Android uses the following regex to parse the limit clause of a query:
From <framework/base/core/java/android/database/sqlite/SQLiteQueryBuilder.java>
LIMIT clause is checked with following sLimitPattern.
private static final Pattern sLimitPattern = Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?");
Note that the regex does accept the format offsetNumber,limitNumber even though it doesn't accept the OFFSET statement directly.
Due to this bug which also doesn't allow for negative limits
8,-1
I had to use this workaround
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(table);
String query = builder.buildQuery(projection, selection, null, null, null, sortOrder, null);
query+=" LIMIT 8,-1";