SQLiteDatabase.query() syntax in Android - android

This query keeps returning errors like error near ?.
public Cursor getRow2( String st, String dr) throws SQLException {
String whereClause = "(adate ?) AND (station ?)";
String[] whereArgs = new String[] { dr, st };
String orderBy = "adate";
Cursor mCursor = db.query(DATABASE_TABLE, columns, whereClause, whereArgs,
null, null, orderBy);
String dr is for "data-range".
If the user does specify the two dates, then dr gets a value like BETWEEN 2004-03-01 AND 2004-06-01.
Othewise dr gets NOT NULL so that the query finds ALL dates.
String st is for "gas station".
If the user provides the station name, st gets a string like 'Shell'.
Otherwise st gets NOT NULL so as to find ALL stations.
Thank you very much.

You can use ? to bind only literals, not partial expressions.
(adate ?) AND (station ?) is not a valid expression. Binding the first arg to BETWEEN 2004-03-01 AND 2004-06-01 and the second Shell makes it essentially
(adate 'BETWEEN 2004-03-01 AND 2004-06-01') AND (station 'Shell')
which is syntactically incorrect.
To use bind args with a query like this, make the query like
(adate BETWEEN ? AND ?) AND (station = ?)
binding args as "2004-03-01", "2004-06-01", "Shell".
For the "not specified" cases it's probably best to use different queries altogether.

Related

Passing parameters into SQLite querys [duplicate]

I am using the query method of SQLiteDatabase. How do I use the query method?
I tried this:
Cursor cursor = sqLiteDatabase.query(
tableName, tableColumns, whereClause, whereArgs, groupBy, having, orderBy);
tableColumns - columns parameter is constructed as follows.
String[] columns = new String[]{KEY_ID, KEY_CONTENT};
If we need to get all the fields, how should the column parameter to be constructed. Do we need to include all the Field Names in String array?
How do I properly use the query method?
tableColumns
null for all columns as in SELECT * FROM ...
new String[] { "column1", "column2", ... } for specific columns as in SELECT column1, column2 FROM ... - you can also put complex expressions here:
new String[] { "(SELECT max(column1) FROM table1) AS max" } would give you a column named max holding the max value of column1
whereClause
the part you put after WHERE without that keyword, e.g. "column1 > 5"
should include ? for things that are dynamic, e.g. "column1=?" -> see whereArgs
whereArgs
specify the content that fills each ? in whereClause in the order they appear
the others
just like whereClause the statement after the keyword or null if you don't use it.
Example
String[] tableColumns = new String[] {
"column1",
"(SELECT max(column1) FROM table2) AS max"
};
String whereClause = "column1 = ? OR column1 = ?";
String[] whereArgs = new String[] {
"value1",
"value2"
};
String orderBy = "column1";
Cursor c = sqLiteDatabase.query("table1", tableColumns, whereClause, whereArgs,
null, null, orderBy);
// since we have a named column we can do
int idx = c.getColumnIndex("max");
is equivalent to the following raw query
String queryString =
"SELECT column1, (SELECT max(column1) FROM table1) AS max FROM table1 " +
"WHERE column1 = ? OR column1 = ? ORDER BY column1";
sqLiteDatabase.rawQuery(queryString, whereArgs);
By using the Where/Bind -Args version you get automatically escaped values and you don't have to worry if input-data contains '.
Unsafe: String whereClause = "column1='" + value + "'";
Safe: String whereClause = "column1=?";
because if value contains a ' your statement either breaks and you get exceptions or does unintended things, for example value = "XYZ'; DROP TABLE table1;--" might even drop your table since the statement would become two statements and a comment:
SELECT * FROM table1 where column1='XYZ'; DROP TABLE table1;--'
using the args version XYZ'; DROP TABLE table1;-- would be escaped to 'XYZ''; DROP TABLE table1;--' and would only be treated as a value. Even if the ' is not intended to do bad things it is still quite common that people have it in their names or use it in texts, filenames, passwords etc. So always use the args version. (It is okay to build int and other primitives directly into whereClause though)
This is a more general answer meant to be a quick reference for future viewers.
Example
SQLiteDatabase db = helper.getReadableDatabase();
String table = "table2";
String[] columns = {"column1", "column3"};
String selection = "column3 =?";
String[] selectionArgs = {"apple"};
String groupBy = null;
String having = null;
String orderBy = "column3 DESC";
String limit = "10";
Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
Explanation from the documentation
table String: The table name to compile the query against.
columns String: A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data
from storage that isn't going to be used.
selection String: A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing
null will return all rows for the given table.
selectionArgs String: 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.
groupBy String: A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null
will cause the rows to not be grouped.
having String: A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING
clause (excluding the HAVING itself). Passing null will cause all row
groups to be included, and is required when row grouping is not being
used.
orderBy String: How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the
default sort order, which may be unordered.
limit String: Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Where clause and args work together to form the WHERE statement of the SQL query. So say you looking to express
WHERE Column1 = 'value1' AND Column2 = 'value2'
Then your whereClause and whereArgs will be as follows
String whereClause = "Column1 =? AND Column2 =?";
String[] whereArgs = new String[]{"value1", "value2"};
If you want to select all table columns, i believe a null string passed to tableColumns will suffice.
if your SQL query is like this
SELECT col-1, col-2 FROM tableName WHERE col-1=apple,col-2=mango
GROUPBY col-3 HAVING Count(col-4) > 5 ORDERBY col-2 DESC LIMIT 15;
Then for query() method, we can do as:-
String table = "tableName";
String[] columns = {"col-1", "col-2"};
String selection = "col-1 =? AND col-2=?";
String[] selectionArgs = {"apple","mango"};
String groupBy =col-3;
String having =" COUNT(col-4) > 5";
String orderBy = "col-2 DESC";
String limit = "15";
query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
db.query(
TABLE_NAME,
new String[] { TABLE_ROW_ID, TABLE_ROW_ONE, TABLE_ROW_TWO },
TABLE_ROW_ID + "=" + rowID,
null, null, null, null, null
);
TABLE_ROW_ID + "=" + rowID, here = is the where clause. To select all values you will have to give all column names:
or you can use a raw query like this
db.rawQuery("SELECT * FROM permissions_table WHERE name = 'Comics' ", null);
and here is a good tutorial for database.

How to query using SQLiteDatabase.query

How can I make query using SQLiteDatabase.query ?
"Select * from table where col1 = something AND col2 IS NOT NULL"
I tried it by putting the col2 with a =? in selection String and NOT NULL in selection argument but it doesn't work.
Please tell me where m going wrong.
selectionArgs is an array of strings, and can be used only for string values.
When you use col2 = ? with the string NOT NULL, you are telling the database to check if the column's value is the eight-character string "NOT NULL".
You must write col2 IS NOT NULL directly into the selection string:
db.query("MyTable", null,
"col1 = ? AND col2 IS NOT NULL",
new String[] { "something" },
null, null, null);
You can use Cursor and rawQuery
Cursor c=db.rawQuery(your_query,null)
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
Query the given table, returning a Cursor over the result set.
Parameters
table The table name to compile the query against.
columns
A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
selection
A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
selectionArgs
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.
groupBy
A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
having
A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
orderBy
How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
So you can try like this
String[] args = { "first string", "second#string.com" };
Cursor cursor = db.query("TABLE_NAME", null, "name=? AND email=?", args, null,null,null);

Android: Getting row by id

I'm trying to get database row by it's ID, but somehow query doesn't return that row. The sql query SELECT * From Table1 Where _id = 100 works good, so I don't know what's the reason. Here is the code of the query:
String [] selectedArgs = new String [] {String.valueOf(selectedItemId)};
String selection = Tables.Table1.COLUMN_ID + "=?";
String [] columns = {Tables.Table1.COLUMN_ID, Tables.Table1.COLUMN_NAME};
Cursor c = foodDB.query(Tables.Food.TABLE_NAME, columns, selection, selectedArgs, null, null, null);
Does anybody have any suggestions?
The problem is that your ID field is a number, while the parameter is a string; the query function does not allow other parameter types for some strange reason.
Try using an expression like COLUMN_ID + " = CAST(? AS INTEGER)".
If your query had only one result column, you could use a separate SQLiteStatement object where you'd be able to use bindLong().
Just in case somebody need it, i have used rawQuery() method for such type of query to work, because query() doesn't work.

Understanding SQLite Cursor Behavior

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);

Android sql query using WHERE clause

Dear Stack Overflow Community,
I have a question regarding how to incorporate a WHERE clause when querying a sql database in Android. My goal is to return specific records from my database where the date picked by a datepicker matches the date stored.
Here is my code:
private static String datePickerDate = "3/29/2011";
private static String[] FROM = { _ID, NAME, PRICE, DATE, TIME };
private static String ORDER_BY = TIME + " DESC ";
private static String WHERE = DATE + "is like " + datePickerDate;
private Cursor getEvents(){
// Perform a managed Query. The Activity will handle closing
// and re-querying the cursor when needed
SQLiteDatabase db = events.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null, null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
My questions are thus:
Where does my "WHERE" statement go?
And is my "WHERE" statement correct?
The documentation I found for db.query doesn't specify if a "WHERE" clause can be used, it just specifies that a "HAVING" clause is possible, but I don't quite think that's what I'm wanting.
db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy)
The selection represents your WHERE clause.
From the doc
selection A filter declaring which
rows to return, formatted as an SQL
WHERE clause (excluding the WHERE
itself). Passing null will return all
rows for the given table.
So you can try this (untested):
private static String WHERE = "DATE like ?";
db.query(table, columns, WHERE , new String[] { datePickerDate }, groupBy, having, orderBy)
If you want to use the WHERE clause, I would suggest using the raw query function in the SQLiteDatabase class, shown here.
This way, you can have the raw query typed out (or in segments) as if you were doing it naturally with SQL.
EDIT: On a side note, the "selection" parameter of the query() function corresponds to the WHERE clause, as noted here
About where you're "WHERE" goes - look here
And regarding the second part, I think you miss the qouts before and after the value, it should be .. like '3/29/2011' and not .. is like 3/29/2011

Categories

Resources