Comparing TEXT variables doesn't work - android

I'm running into problems when I try to compare TEXT on my Android SQLite DB.
I have a query like that:
select * from myTable where _id='some.text.dots.are.really.there!'
myTable is TEXT PRIMARY KEY. I'm trying to select and update some data in my table. There are there and get returned when I do a SELECT *.
The Android code (with where clause) looks like that:
mDb.query(TABLE_TRANSACTIONS, TABLE_TRANSACTIONS_COLUMNS, COLUMN__ID + " = ?",
new String[] {id }, null, null, null);
But
mDb.query(TABLE_TRANSACTIONS, TABLE_TRANSACTIONS_COLUMNS, COLUMN__ID + " = '" + id + "'",
null, null, null, null);
works neither. How do I compare TEXT values in SQLite on Android?

SQLite also considers the TEXT CASE (UPER CASE/LOWER CASE) while comparing string, so you can use COLLATE NOCASE, which forces SQLite to ignore TEXT CASE.
Try this:
SELECT *
FROM myTable
WHERE _id='some.text.dots.are.really.there!'
COLLATE NOCASE;
You can use rawQuery for SELECT:
mDb.rawQuery('Query Here',null);
and executeQuery for INSERT/UPDATE/DELET:
mDb.executeQuery('Query Here',null);

I have found the problem: The routines are salting the IDs and therefore they differ from the plain text string.
Stupid error ... Anyways, thank you guys.

Related

Select date range from sqlite

I really need your help.
I have problem getting values from database. I have two editTexts and one Button. When I insert dates and press Button my table opens without data. How can I get for my database to read those editText values?
My code:
String val1=minDate.getText().toString();
String val2=maxDate.getText().toString();
Cursor c=database.rawQuery("SELECT * from TABLE WHERE DATE BETWEEN '"+ val1+"' AND '"+ val2+"' ", null);
Please refer to documentation:
http://developer.android.com/guide/topics/data/data-storage.html#db
To avoid SQL injection, never add parameter to query by concatenating values, To create a query please refer to: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#query%28java.lang.String,%20java.lang.String[],%20java.lang.String,%20java.lang.String[],%20java.lang.String,%20java.lang.String,%20java.lang.String%29
Security tip:
http://developer.android.com/training/articles/security-tips.html#ContentProviders
How date are stored in your table ? Which format ?
When you add parameter to your query format must be the same.
If you want to use BETWEEN key word, date must be stored in this format: year-month-date to be sorted by SQLite.
Update 1
You're right change date format to yyyy-mm-dd
You parameters in your query must have same format, of course.
Put query in variable and log it before, as this:
String query = "SELECT * from TABLE WHERE DATE BETWEEN '"+ val1+"' AND '"+ val2+"' ";
Log.d("MyQuery", query);
Cursor c=database.rawQuery(query, null);
Search in logcat TAG "MyQuery" and post value of query
Now replace your code with below and let me know what you got in Logs
Cursor cursor=database.rawQuery("SELECT * from TABLE WHERE DATE >='"+val1+ "' AND <= '"+val2+ "'", null);
if (cursor.moveToFirst()) {
do {
Log.i("cursor_Data",cursor.getString(cursor.getColumnIndex("Date")));
} while (cursor.moveToNext());
}
If above not work for you then please post your TABLE Structure?

Single quote (') in edittext makes my program crash

If I write something into an edittext that contains single quote (') my program crashes. With this edittext I can search for things in my database and some of them contain this single qoute (or apostrophe whatever name it has but the point is that it's about the single qoute). I assume it has some special functions and this is why it crashes. Is there any option to ignore its function or solve this problem somehow?
for example, an item in my database:
cv.put(KEY_NAME, "Jonh's idea");
cv.put(KEY_HOTNESS, "amazing");
cv.put(KEY_MONEY, "500");
ourDatabase.insert(DATABASE_TABLE, null, cv);
Then when I search for it with this method:
return ourDatabase.query(DATABASE_TABLE, new String[] {"_id", "idea_name",},
"idea_name like " + "'%" + qq + "%'", null, null, null, null);
where qq is given by the user (for example Jonh's idea), it crahses. And yes, I get syntax error.
Sounds like the ' is causing an SQL injection of some sort... the ' is causing a syntax error in your SQL statement. There are several things you might consider double checking:
rawQuery() will not protect you from SQL injections, so avoid using it (rather, use the query, insert, update, and delete methods instead).
Prefer formatting your selection and selectionArgs as follows (as it will protect you from SQL injections):
selection = "col_1 = ?";
selectionArgs = new String[] { "value_1" };
(note that the values in the String[] replace the ?s in the selection string).
Set an inputType on your EditText to prevent users from entering these characters in the first place (i.e. if you only want users to enter numbers, then set android:inputType="number").
Overall, as long as you correctly make use of the Android methods in the SQLiteDatabase class, you shouldn't run into any problems with SQL injections (Android does a good job at cleaning this up for you). That said, if you don't choose to make use of these special-purpose methods, then you should check the content of the String at runtime and protect against characters such as ', ;, ", etc. by escaping them.
You can refer to this post for more information:
Android Single Quote In SQL With a LIKE StateMent
You need to use the selectionArgs argument to escape the string (so that the single quote in it doesn't break the SQL). Try something like this:
return ourDatabase.query(DATABASE_TABLE, new String[] {"_id", "idea_name",}, "idea_name like ?", new String[] { "%" + qq + "%" }, null, null, null);
It seems like SQL-injection. U have to escape your input.
One more jugaad. You can replace ' with `. You won't have to recheck your code. Just modify the following:
String input = edittext.getText().toString();
if(input.contains("'"))
{
input = input.replace("'", "`");
}
//now proceed with the database operation ...
This will enable the user to input text like RD's jugaad to RD`s jugaad

How to prevent duplicating SQLite database in android?

My app reads an XML file on the internet, takes note of the time and creates/writes an SQLite database. The next time data is required, if the time is >24hrs the database is updated (xml downloaded again).
The problem is that whenever I relaunch the app in AVD it has to re-download and so I notice that all the data in the database is written again (duplicated). So instead of 10 items, I have 20 (10+10 duplicates). If I relaunch again I get another 10 items duplicated.
I thought about how I could prevent the duplication of the database (or delete the old entries), so I decided to increment the database version every time the content is downloaded. I thought this would trigger the onUpgrade() method so the data would be cleared but nothing changes.
Now I am clueless. How should I go about this?
On your database create you'll want to use the UNIQUE constraint. You may not want the ON CONFLICT REPLACE that i use, but you should get the idea.
For Ex:
private static final String DATABASE_CREATE_NEWS= "create table news (_id integer primary key autoincrement, "title text not null, description text not null, date text not null, LastModified text not null, UNIQUE(title, date) ON CONFLICT REPLACE);";
Here is another solid thread that talks about it as well.
SQLite table constraint - unique on multiple columns
Here is some more info on the android sqlite: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
You should create an index on the columns that represent a unique identifier.
see this article on SQLite's website.
CREATE INDEX ix_tblexample ON TableName ( Column1, Column2, Column3 [, Column4, etc..])
Or (as per your comment) you can select the table into a cursor and check for each one.
String sql = "select * from " + tableName + "where column1 = " + param1 + "and column2 = " + param2;
Cursor cur = _db.rawQuery( sql, new String[0] );
if(cur.getCount() == 0)
{
//upload
}

Android - SimpleAdapter filter query, how to ignore accents?

I am currently using the ContentProvider for contacts to retrieve the contacts from the device and allowing the user to filter the results by typing into an EditText.
To do so I have set up a filter query on a SimpleAdapter as follows:
contactsAdapter.setFilterQueryProvider(new FilterQueryProvider() {
String[] PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
};
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED COLLATE NOCASE ASC";
public Cursor runQuery(CharSequence constraint) {
String SELECTION = "LOWER(" + ContactsContract.Contacts.DISPLAY_NAME + ")"
+ " LIKE '" + constraint + "%' " + "and " + ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
Cursor cur = managedQuery(ContactsContract.Contacts.CONTENT_URI,
PROJECTION, SELECTION, null, sortOrder);
return cur;
}
});
setListAdapter(contactsAdapter);
This works in most cases however when I have a contact with an accent (Example: Tést Cóntact) then I want the contact to show up even if the user types in Test Contact, currently it doesn't.
Also the case is not ignored in this case either whereas for standard characters it is, for example if I have a contact called Omar and search for omar it matches but if I have a contact called Ómar and search for ómar it doesn't match.
Does anyone know what I should be doing to implement the behavior I want to achieve?
I would see 2 options here :
Create a table that contains accent-less version of the contacts names and a reference to the actual contact Id
Replace accented caracters by ? in your search (which may result in not really user expected behaviour, but is so much simpler)
See my question Using COLLATE in Android SQLite - Locales is ignored in LIKE statement
Short answer - I think it's impossible to use the LIKE statement in Android SQLite and ignore accents. I solved it by making a new column in the database, where you store the same name without accents and in lower case. For example Column 1 stores "Tést Cóntact" - which is used for display and Column 2 stores "test contact" - which is used for using the LIKE statement.
Android 2.3 has a Normalizer class which will remove all accents from a string. If you are supporting lower Android API, then you may need to write your own normalizer somehow...
You can use the replace function to remove the accented characters. Look at this simple solution:
How to SQL compare columns when one has accented chars?

How to import sqlite file into my project?

I am making an sqlight using eclipse outside the android project
what should I add into my android manifest in order to make it work?
thank you Mathias, lets take this q to another project who generate a SQL file using java
assuming this. How can I set the SQLiteDatabase.NO_LOCALIZED_COLLATORS flag when calling SQLiteDatabase.openDatabase()?
my code over there is
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db");
/*
*some code
*/
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists "+TABLE_NAME+";");
//stat.executeUpdate("create table "+TABLE_NAME+" (name, occupation);");
stat.executeUpdate("create table "+TABLE_NAME+" ("+VALUE+","+TYPE+","+LETTER+");");
PreparedStatement prep = conn.prepareStatement(
"insert into "+TABLE_NAME+" values (?, ?,?);");
Even when I use:
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
when I use the query :
String s = "Israel";
Cursor cursor = db.query(TABLE_NAME, new String[] {VALUE}
,VALUE + " like " + "'%" + s +"%'", null, null, null, null);
I get an exception .
You don't need to add anything special into the android manifest. You can open the database from anywhere, i.e. also from your sdcard or else. Otherwise, A common place to put the database is in to the assets folder of your application.
When you create the db outside the android project, just make sure you either create the metadata table (as mentioned in the Android docs) or set the SQLiteDatabase.NO_LOCALIZED_COLLATORS flag when calling SQLiteDatabase.openDatabase(). Also you should note that the primary key in all tables is _id. These are the most important things to consider when creating a new DB.
Also helpful regarding the metadata-table might be:
What is the android_metadata table?
No such table android_metadata, what's the problem?
Helpful blog:
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/

Categories

Resources