I select data from my sqlite database. My problem is that when in database are apostrophes ("I' m John" - for example) and i try to select data, then my application crash.
If i don' t have apostrophes in database, then everything is all right.
My select data function:
String query = "SELECT * FROM " + mainCollumn + " WHERE used=0 " + " AND season <= " + seasons + " ORDER BY RANDOM() LIMIT " + count ;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
if(cursor.moveToFirst()){
do {
Question question = new Question(Integer.parseInt(cursor.getString(0)),
cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getString(4),cursor.getString(5),
Integer.parseInt(cursor.getString(6)));
questionList.add(question);
}while(cursor.moveToNext());
}
Thanks for any help.
You can specially handle apostrophes by replacing them with double apostrophes, but the best way is to use query() with selectionArgs instead of rawQuery().
SQLiteDatabase db = this.getReadableDatabase();
String[] columns = new String[] {column1, column2}; // the columns you want
Cursor cursor = db.query(mainCollumn, String[] columns, "used=0 and season<=?", new String[] {seasons}, null, null, "RANDOM() LIMIT " + count);
This is an issue with any SQL as single quote (apostrophe) is the text delimiter character. In your data, you must either replace apostrophe with another character or replace single apostrophes with double apostrophes.
Daniel O'Neil
becomes
Daniel O''Neil
[EDIT]
UgglyNoodles's recommendation is better.
Related
I'm making an Android app and using a SQLite database. In particular I'm using the rawQuery method on a database obtained through a SQLiteOpenHelper. The query I build makes use of the ? marks as placeholders for the real values, which are passed along as an array of objects (e.g., select * from table where id = ?).
The question is, is it possible to get the query with the marks already replaced, at least from the cursor returned from the rawQuery method? I mean something like select * from table where id = 56. This would be useful for debugging purposes.
It's not possible. The ? values are not bound at the SQL level but deeper, and there's no "result" SQL after binding the values.
Variable binding is a part of the sqlite3 C API, and the Android SQLite APIs just provide a thin wrapper on top. http://sqlite.org/c3ref/bind_blob.html
For debugging purposes you can log your SQL with the ?, and log the values of your bind arguments.
You could form it as a string like this
int id = 56;
String query = "select * from table where id = '" + id + "'";
and then use it as a rawQuery like this (if I understood your question properly)
Cursor mCursor = mDb.rawQuery(query, null);
You can also use the SQLiteQueryBuilder. Here is an example with a join query:
//Create new querybuilder
SQLiteQueryBuilder _QB = new SQLiteQueryBuilder();
//Specify books table and add join to categories table (use full_id for joining categories table)
_QB.setTables(BookColumns.TABLENAME +
" LEFT OUTER JOIN " + CategoryColumns.TABLENAME + " ON " +
BookColumns.CATEGORY + " = " + CategoryColumns.FULL_ID);
//Order by records by title
_OrderBy = BookColumns.BOOK_TITLE + " ASC";
//Open database connection
SQLiteDatabase _DB = fDatabaseHelper.getReadableDatabase();
//Get cursor
Cursor _Result = _QB.query(_DB, null, null, null, null, null, _OrderBy);
App won't run - trying to execute query to print certain value
Method:
public Cursor trying(String vg){
String q="SELECT quantity FROM " + TABLE_CONTACTS + " WHERE name=" + vg;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(q,null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
Calling method from main
Cursor wow = db.trying("gold");
text = (TextView) findViewById(R.id.textView13);
text.setText((CharSequence) (wow));
At first. Since you are directly adding trying variables into statement, variable must be wrapped to single quotes or it's interpeted as column.
"SELECT quantity FROM " + TABLE_CONTACTS + " WHERE name= '" + vg + "'";
And second "big" problem, look here:
text.setText((CharSequence) (wow));
Here you are trying to cast Cursor to CharSequence but it's not possible. If you want to retrieve data from Cursor you have to use one from the getters methods of Cursor class in your case getString() method:
String quantity = wow.getString(0); // it returns your quantity from Cursor
text.setText(quantity);
Now it should works.
Recommendation:
I suggest you to an usage of parametrized statements which actually use placeholders in your queries. They provide much more safer way for adding and retrieving data to / from database.
Let's rewrite your code:
String q = "SELECT quantity FROM " + TABLE_CONTACTS + " WHERE name = ?";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(q, new String[] {vg});
It works simply. Placeholder ? will be replaced with your string value.
I am working on a database with sqllite in an android app
I want to retrieve sm data using a like clause
ex:
Cursor c = myDB.query(MY_DATABASE_TABLE, null, " SongName LIKE '%"+"=?"+"%'" ,
new String[]{match_str}, null, null,"SongHit DESC");
It should give all SongName starting with match_str but its not working.Why?
This:
" SongName LIKE '%"+"=?"+"%'"
Will end up looking like this when the SQL interpreter sees it:
" SongName LIKE '%=?%'"
And that will match any SongName that contains a literal "=?" and I don't think that's anything like what you want.
A % matches any sequence of characters in an SQL LIKE, it is essentially the same as .* in a regular expression; so, if you want to match at the beginning then you don't want a leading %. Also, your ? placeholder needs to be outside the single quotes or it will be interpreted as a literal question mark rather than a placeholder.
You want something more like this:
String[] a = new String[1];
a[0] = match_str + '%';
Cursor c = myDB.rawQuery("SELECT * FROM songs WHERE SongName LIKE ?", a);
If you wanted to be really strict you'd also have to escape % and _ symbols inside match_str as well but that's left as an exercise for the reader.
Try this:
String[] args = new String[1];
args[0] = "%"+song+"%";
Cursor friendLike = db.rawQuery("SELECT * FROM songs WHERE SongName like ?", args);
No need for the equal sign and you should be able to include the ? right in the string without the need for the + operator. The where clause should just be:
"SongName LIKE '%?%'"
and if mu is too short is correct and you only want starting with...
"SongName LIKE '?%'"
hi Are you getting any exception while executing the above query. Try by removing the "=" symbol infront of the question mark in the like condition. Else try using
db.rawQuery(sql, selectionArgs)
This works perfectly for me...
"Songname LIKE ? "...
cursor = database.rawQuery(query, new String[]{"%" + searchTerm + "%"});
If you wish to use query() instead of rawQuery(), you can do it like so:
// searchString is the string to search for
final String whereClause = "MyColumnName" + " like ?";
String[] whereArgs = new String[]{"%" + searchString + "%"};
Cursor cursor = sqLiteDatabase.query("MyTableName",
null, // columns
whereClause, // selection
whereArgs, // selectionArgs
null, // groupBy
null, // having
null, // orderBy
null); // limit
a simple way is to use the concatenate operator ||
"SongName LIKE '%'||?||'%'"
so there is no need to edit the match_str.
Cursor c = myDB.query(MY_DATABASE_TABLE, null, " SongName LIKE '%'||?||'%'" ,
new String[]{match_str}, null, null,"SongHit DESC");
from https://stackoverflow.com/a/46420813/908821
I'm trying to create a simple Login form, where I compare the login id and password entered at the login screen with that stored in the database.
I'm using the following query:
final String DATABASE_COMPARE =
"select count(*) from users where uname=" + loginname + "and pwd=" + loginpass + ");" ;
The issue is, I don't know, how can I execute the above query and store the count returned.
Here's how the database table looks like ( I've manged to create the database successfully using the execSQl method)
private static final String
DATABASE_CREATE =
"create table users (_id integer autoincrement, "
+ "name text not null, uname primary key text not null, "
+ "pwd text not null);";//+"phoneno text not null);";
Can someone kindly guide me as to how I can achieve this? If possible please provide a sample snippet to do the above task.
DatabaseUtils.queryNumEntries (since api:11) is useful alternative that negates the need for raw SQL(yay!).
SQLiteDatabase db = getReadableDatabase();
DatabaseUtils.queryNumEntries(db, "users",
"uname=? AND pwd=?", new String[] {loginname,loginpass});
#scottyab the parametrized DatabaseUtils.queryNumEntries(db, table, whereparams) exists at API 11 +, the one without the whereparams exists since API 1. The answer would have to be creating a Cursor with a db.rawQuery:
Cursor mCount= db.rawQuery("select count(*) from users where uname='" + loginname + "' and pwd='" + loginpass +"'", null);
mCount.moveToFirst();
int count= mCount.getInt(0);
mCount.close();
I also like #Dre's answer, with the parameterized query.
Use an SQLiteStatement.
e.g.
SQLiteStatement s = mDb.compileStatement( "select count(*) from users where uname='" + loginname + "' and pwd='" + loginpass + "'; " );
long count = s.simpleQueryForLong();
See rawQuery(String, String[]) and the documentation for Cursor
Your DADABASE_COMPARE SQL statement is currently invalid, loginname and loginpass won't be escaped, there is no space between loginname and the and, and you end the statement with ); instead of ; -- If you were logging in as bob with the password of password, that statement would end up as
select count(*) from users where uname=boband pwd=password);
Also, you should probably use the selectionArgs feature, instead of concatenating loginname and loginpass.
To use selectionArgs you would do something like
final String SQL_STATEMENT = "SELECT COUNT(*) FROM users WHERE uname=? AND pwd=?";
private void someMethod() {
Cursor c = db.rawQuery(SQL_STATEMENT, new String[] { loginname, loginpass });
...
}
Assuming you already have a Database (db) connection established, I think the most elegant way is to stick to the Cursor class, and do something like:
String selection = "uname = ? AND pwd = ?";
String[] selectionArgs = {loginname, loginpass};
String tableName = "YourTable";
Cursor c = db.query(tableName, null, selection, selectionArgs, null, null, null);
int result = c.getCount();
c.close();
return result;
how to get count column
final String DATABASE_COMPARE = "select count(*) from users where uname="+loginname+ "and pwd="+loginpass;
int sometotal = (int) DatabaseUtils.longForQuery(db, DATABASE_COMPARE, null);
This is the most concise and precise alternative. No need to handle cursors and their closing.
If you are using ContentProvider then you can use:
Cursor cursor = getContentResolver().query(CONTENT_URI, new String[] {"count(*)"},
uname=" + loginname + " and pwd=" + loginpass, null, null);
cursor.moveToFirst();
int count = cursor.getInt(0);
If you want to get the count of records then you have to apply the group by on some field or apply the below query.
Like
db.rawQuery("select count(field) as count_record from tablename where field =" + condition, null);
Another way would be using:
myCursor.getCount();
on a Cursor like:
Cursor myCursor = db.query(table_Name, new String[] { row_Username },
row_Username + " =? AND " + row_Password + " =?",
new String[] { entered_Password, entered_Password },
null, null, null);
If you can think of getting away from the raw query.
int nombr = 0;
Cursor cursor = sqlDatabase.rawQuery("SELECT column FROM table WHERE column = Value", null);
nombr = cursor.getCount();
Background
I have an Android project that has a database with two tables: tbl_question and tbl_alternative.
To populate the views with questions and alternatives I am using cursors. There are no problems in getting the data I need until I try to join the two tables.
Tbl_question
-------------
_id
question
categoryid
Tbl_alternative
---------------
_id
questionid
categoryid
alternative
I want something like the following:
SELECT tbl_question.question, tbl_alternative.alternative where
categoryid=tbl_alternative.categoryid AND tbl_question._id =
tbl_alternative.questionid.`
This is my attempt:
public Cursor getAlternative(long categoryid) {
String[] columns = new String[] { KEY_Q_ID, KEY_IMAGE, KEY_QUESTION, KEY_ALT, KEY_QID};
String whereClause = KEY_CATEGORYID + "=" + categoryid +" AND "+ KEY_Q_ID +"="+ KEY_QID;
Cursor cursor = mDb.query(true, DBTABLE_QUESTION + " INNER JOIN "+ DBTABLE_ALTERNATIVE, columns, whereClause, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
I find this way to form queries harder than regular SQL, but have gotten the advice to use this way since it is less error prone.
Question
How do I join two SQLite tables in my application?
You need rawQuery method.
Example:
private final String MY_QUERY = "SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.other_id WHERE b.property_id=?";
db.rawQuery(MY_QUERY, new String[]{String.valueOf(propertyId)});
Use ? bindings instead of putting values into raw sql query.
An alternate way is to construct a view which is then queried just like a table.
In many database managers using a view can result in better performance.
CREATE VIEW xyz SELECT q.question, a.alternative
FROM tbl_question AS q, tbl_alternative AS a
WHERE q.categoryid = a.categoryid
AND q._id = a.questionid;
This is from memory so there may be some syntactic issues.
http://www.sqlite.org/lang_createview.html
I mention this approach because then you can use SQLiteQueryBuilder with the view as you implied that it was preferred.
In addition to #pawelzieba's answer, which definitely is correct, to join two tables, while you can use an INNER JOIN like this
SELECT * FROM expense INNER JOIN refuel
ON exp_id = expense_id
WHERE refuel_id = 1
via raw query like this -
String rawQuery = "SELECT * FROM " + RefuelTable.TABLE_NAME + " INNER JOIN " + ExpenseTable.TABLE_NAME
+ " ON " + RefuelTable.EXP_ID + " = " + ExpenseTable.ID
+ " WHERE " + RefuelTable.ID + " = " + id;
Cursor c = db.rawQuery(
rawQuery,
null
);
because of SQLite's backward compatible support of the primitive way of querying, we turn that command into this -
SELECT *
FROM expense, refuel
WHERE exp_id = expense_id AND refuel_id = 1
and hence be able to take advanatage of the SQLiteDatabase.query() helper method
Cursor c = db.query(
RefuelTable.TABLE_NAME + " , " + ExpenseTable.TABLE_NAME,
Utils.concat(RefuelTable.PROJECTION, ExpenseTable.PROJECTION),
RefuelTable.EXP_ID + " = " + ExpenseTable.ID + " AND " + RefuelTable.ID + " = " + id,
null,
null,
null,
null
);
For a detailed blog post check this
http://blog.championswimmer.in/2015/12/doing-a-table-join-in-android-without-using-rawquery
"Ambiguous column" usually means that the same column name appears in at least two tables; the database engine can't tell which one you want. Use full table names or table aliases to remove the ambiguity.
Here's an example I happened to have in my editor. It's from someone else's problem, but should make sense anyway.
select P.*
from product_has_image P
inner join highest_priority_images H
on (H.id_product = P.id_product and H.priority = p.priority)