I am trying to fetch data which contains specific string but query is not working, following is method for fetching data.
public Cursor getSearch(String item) {
SQLiteDatabase db = this.getReadableDatabase();
String mQuery = "SELECT * FROM hadiths WHERE text LIKE %"+item.toString()+"%";
Cursor cursor = db.rawQuery(mQuery, null);
return cursor;
}
Logcat shows following error.
Caused by: android.database.sqlite.SQLiteException: near "%": syntax error (code 1): , while compiling: SELECT * FROM hadiths WHERE text LIKE %fast%
I know that the wildcard %% and string variable item is causing issue but how do I use string variable along with wildcard?
Edit:
As mentioned below by Jiří, parameters should be used to help prevent SQL injection issues.
In order to add parameters you could do something similar to this:
String mQuery = "SELECT * FROM hadiths WHERE text LIKE ?”;
String param1 = “%” + item + ”%”;
Cursor cursor = db.rawQuery(mQuery, new String [] {param1});
In order to add another parameter:
String mQuery = "SELECT * FROM hadiths WHERE text LIKE ? AND Name = ?”;
String param1 = “%” + item + ”%”;
String param2 = name;
Cursor cursor = db.rawQuery(mQuery, new String [] {param1, param2});
This code is a bit cumbersome, but it is to illustrate that the parameters must be added in the order in which they are should be added to the query.
see SQLite documentation:
https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase
Original answer here for posterity. WARNING Dangerous SQL injection issue!
You need to add single quotes to the query.
String mQuery = "SELECT * FROM hadiths WHERE text LIKE '%"+item+"%'";
Take a look at the SQLite docs:
https://www.tutorialspoint.com/sqlite/sqlite_like_clause.htm
Note: There is no need to use toString() since "item" is already of type String.
Related
I tried to calculate a report and displays the result in the texview "edt1". But it's not displayed.
there is mydatabasehelper :
public void calculrapport(Argent a)
{
db = this.getWritableDatabase();
String query = "select sum(Entree) from Argent where date between \"datedebut\" and \"datefin\" ;";
Cursor cursor = db.rawQuery(query , null) ;
int count = cursor.getCount();
}
There is my class Rapport.java :
public void onOKClick ( View v ) {
if (v.getId() == R.id.okrapport) {
EditText datedebut = (EditText) findViewById(R.id.datedebut);
EditText datefin = (EditText) findViewById(R.id.datefin);
String strdatedebut = datedebut.getText().toString();
String strdatefin = datefin.getText().toString();
Argent a = new Argent();
helper.calculrapport(a);
edt1.setText( );
}
}
Thanks in advance.
Assuming that the query works as expected (especially considering that variables used have the appropriate scope, which would appear unlikely perhaps try using select sum(Entree) from Argent to test without the complications of wheteher or not the datedebut and datefin variables can resolve and if so resolve to usable values) then you need to :-
Extract the appropriate value and return the value from the method and then use the returned value to set the text in the TextView.
To return the value the method should not be void, but have an appropriate return type (String will be used for the example),
so instead of public void calculrapport(Argent a), use public String calculrapport(Argent a) (thus the method will be required to return a string)
To extract the value the cursor needs to be moved to the appropriate row (there should only be the one row as the sum function is an aggregate function and there is only the one group (aggregate functions work on gropus) i.e. all rows)
As such the method could be :-
public String calculrapport(Argent a)
{
String rv = "0"; //<<<< used to return 0 if no rows are selected by the query
db = this.getWritableDatabase();
String query = "select sum(Entree) from Argent where date between \"datedebut\" and \"datefin\" ;";
Cursor cursor = db.rawQuery(query , null) ;
if (cursor.moveToFirst()) {
rv = cursor.getString(0); //<<<< get the value from the 1st (only) column
}
cursor.close(); //<<<< Cursors should always be closed when done with
return rv;
}
To set the TextView with the returned value instead of using :-
helper.calculrapport(a);
edt1.setText( );
Use :-
edt1.setText(helper.calculrapport(a));
Or :-
String sum = helper.calculrapport(a);
edt1.setText(sum);
Additional re comment:-
The problem is located in the SQlite query (select sum(Entree) from
Argent where date between \"datedebut\" and \"datefin\" ;) exactly
when we call "datedebut" and "datefin" taht located in the class
rapport.java
Then String query = "select sum(Entree) from Argent where date between \"datedebut\" and \"datefin\" ;";
resolves to :-
select sum(Entree) from Argent where date between "datedebut" and "datefin" ;
I believe, assuming that datedebut and datefin are string variables, and that they are in a valid SQLite date format e.g. they could be 2018-01-01 and 2018-02-01 (and that values in the date column are formatted as a valid SQLite date format) that you should instead be using :-
String query = "select sum(Entree) from Argent where date between '" + datedebut + "' and '" + datefin +"' ;";
Which would then resolve to something like :-
SELECT sum(entree) FROM argent WHERE date BETWEEN '2018-01-01' AND '2018-02-01';
For valid SQLite date formats; refer to Date And Time Functions
Note the above is in-principle code and has not been tested so may contain some simple typing errors.
I know it is a basic question, but i can not find problem.
I try to get some columns with rawQuery.
SQLiteDatabase db=database.getReadableDatabase();
try
{
String sql="SELECT * FROM CAR WHERE name = ";
Cursor crs = db.rawQuery(sql+"5P", null);
}
I always get the same exception.
android.database.sqlite.SQLiteException: **unrecognized token**: "5P": , while compiling: SELECT * FROM CAR WHERE name = 5P
I have 5P at CAR table, i am sure because i used it other queries.
You either need to quote that value, or better yet, use positional parameters:
String[] args={"5P"};
Cursor crs=db.rawQuery("SELECT * FROM CAR WHERE name = ?", args);
The advantage of using positional parameters is that SQLite will handle quoting the string, escaping any embedded quotes, etc.
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.
I am trying to explore android and I just started using SQLite database. I'm wondering on what is the right syntax for selecting a single row from a table, where the row I want to select is from the value entered from a user using editText. Thanks in advance.
I'm going to disagree with both of the answers above. What if the user enters this query:
Bobby Tables'; drop table yourTable;
See: http://xkcd.com/327/
I believe you should do this instead:
String query = "select * from TABLE_NAME WHERE column_name=?";
String[] selection = new String[1];
selection[0] = users_entered_value;
Cursor c = db.rawQuery(query, selection);
ETA: Actually, the more I think about it, the more I think you're going in the wrong direction. If your app depends on a database query returning exactly one unique match to an arbitrary string entered by the user, it's probably going to be broken a great deal of the time.
What you should probably do is something like this:
String query = "select * from TABLE_NAME WHERE column_name LIKE ?";
String[] selection = new String[1];
selection[0] = "%" + users_entered_value + "%";
Cursor c = db.rawQuery(query, selection);
and then iterate through the results and pick a "best" match according to your own criteria.
Also, you should create the table with case-insensitive matching for the column(s) you're going to be searching.
SQLiteDatabase db;
db.rawQuery("select * from yourTable where your_column_name = 'users_entered_value' limit 1", null);
SQLiteDatabase db;
// make connection to your database ;
Cursor c = null ;
String SQL = "select * from TABLE_NAME where column_name='VALUE'";
c = db.rawQuery(SQL);
c contains your result array of query you fired.
You can retrieve values using loop.
I am trying to update the database on the basis of incoming parameter but it is not updated.
i am using the following code:
public static void markFavoriteStation(String station, boolean favorite){
Log.d(AppConstants.TAG,"StationListDBIfc: +markFavoriteStation");
String Query = null;
mDb = bartDb.getWritableDatabase();
Query = "update stationlistTable set favorite ='1' where namewithabbr = '+station'";
mDb.rawQuery(Query, null);
Log.d(AppConstants.TAG,"StationListDBIfc: -markFavoriteStation");
}
I think you might have a malformed String definition. You should end the String before concatenating the "station" variable to it, like so:
Query = "update stationlistTable set favorite ='1' where namewithabbr = '" + station + "'";
I can't see any errors. I guess the SQL query has errors or the namewithabbr column doesn't contain what you expect. You should test it in the sqlite3 app.