SQLiteOpenHelper problems - android

I have been working with Android and SQLite Database to develop an application.
But I am having a few problems.
This is my code:
SQLiteHelperMoney SQLiteHelperMoney1 = new SQLiteHelperMoney(this, null, null, 1);
SQLiteDatabase database = SQLiteHelperMoney1.getReadableDatabase();
Cursor cursorCategory = database.query(false, "CATEGORY", null, null, null, null, null, null, null);
SQLiteHelperMoney SQLiteHelperMoney2 = new SQLiteHelperMoney(this, null, null, 1);
SQLiteDatabase database2 = SQLiteHelperMoney2.getReadableDatabase();
Cursor cursorTransaction = database2.query(false, "TRANSACTIONS", null, null, null, null, null, null, "10");
Now the problem is, that in my cursor cursorCategory I get the data that is stored in the Category table of my database. But I do not get any data in the cursorTransaction, why does this happen??
Furthermore, while instantiating my SQLiteHelperMoney2 object, if I change the instantiation of my SQLiteHelperMoney2 object to this :
SQLiteHelperMoney SQLiteHelperMoney2 = new SQLiteHelperMoney(this, "TRANSACTIONS", null, 1);
then I get the data from the Transaction table, in my cursorTransaction.
But why does this happen?? According to the documentation, in the constructor of the SQLiteOpenHelper, the second parameter, is the name of the database, not the name of the table.
Then why does giving the name of the TABLE, in the field NAME OF DATABASE, gives the correct answer?
Furthermore, the documentation says that in the constructor for SQLiteOpenHelper, in the field "NAME" you can specify null if the database is already in the memory. I was assuming that the database had been created in the app itself, so it will be in memory only, that is why I specify the second parameter as null here :
SQLiteHelperMoney SQLiteHelperMoney1 = new SQLiteHelperMoney(this, null, null, 1);
But it works here but not in the other case.
Further, what is the name of database created by default? Because I haven't specified it in my onCreate function of the SQLiteOpenHelper. And can I change the name of my database??
EDIT:
onCreate method:
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE CATEGORY (_ID INTEGER PRIMARY KEY, NAME TEXT)");
db.execSQL("CREATE TABLE TRANSACTIONS (_ID INTEGER PRIMARY KEY, AMOUNT INTEGER, CATEGORY TEXT, NOTE TEXT, TIME TEXT, EXPENSE INTEGER)");
db.execSQL("CREATE TABLE BUDGET (_ID INTEGER PRIMARY KEY, AMOUNT INTEGER, TIME TEXT)");
ContentValues cv = new ContentValues();
cv.put("NAME", "FOOD");
db.insert("CATEGORY", null, cv);
cv.put("NAME", "TRAVEL");
db.insert("CATEGORY", null, cv);
cv.put("NAME", "INCOME");/*INCOME*/
db.insert("CATEGORY", null, cv);
cv.put("NAME", "TRANSPORTATION");
db.insert("CATEGORY", null, cv);
cv.put("NAME", "MOVIE");
db.insert("CATEGORY", null, cv);
}
#laalto: I read your answer here : When is SQLiteOpenHelper onCreate() / onUpgrade() run?
And I'm a bit confused about the on-disk and in-memory database. In my onCreate method, I add rows in my Category table, because I believed that the onCreate method is only called once in the lifetime of the application, i.e., when it is run the first time, for creating the databases.
That is why in my onCreate method I add data into my CATEGORY table, because I wanted it to have some initial data.
And I believed when we make substituent calls to getReadableDatabase() and getWritableDatabase() it returns us a copy of the earlier created database for us to work with, or probably a handle to the original database and on completion saves those changes. But, after reading your answer it seems that the onCreate methods are run every time. If they are run everytime where does the data get stored, since we will loose the database when we close it??

Now the problem is, that in my cursor cursorCategory I get the data that is stored in the Category table of my database. But I do not get any data in the cursorTransaction, why does this happen??
The query returns no data from in the in-memory database you just created.
Furthermore, while instantiating my SQLiteHelperMoney2 object, if I change the instantiation of my SQLiteHelperMoney2 object to this :
...
But why does this happen??
The query returns some data from the on-disk database that has been previously created.
For some coincidence the name of the database file is the same as the table. Uninstall and reinstall your app, or clear its data in the app manager to get rid of possible old database files possibly still around.
Furthermore, the documentation says that in the constructor for SQLiteOpenHelper, in the field "NAME" you can specify null if the database is already in the memory. I was assuming that the database had been created in the app itself, so it will be in memory only
Passing a null creates a new in-memory database. It means a new, empty database that is not persisted to disk. When the database is closed, the data is gone. If you create another in-memory database, it won't see the data in other in-memory databases.
But it works here but not in the other case.
Possibly because the other helper populates the database in its onCreate() and the other doesn't.
Further, what is the name of database created by default?
Nothing. In-memory databases have no name. Named databases get stored on disk with the name you gave.

Related

Avoid duplicate entries in SQLite

I am writing a small application in android to store basic details about person using SQLite.
I insert data using this function
public void insertData(String user,String p_no,SQLiteDatabase db)
{
ContentValues cv = new ContentValues();
cv.put(NAME, user);
cv.put(PHONE, p_no);
db.insert("MYTABLE", null, cv);
}
The above function allows duplicate names to be stored.
So I wrote a function that will first check whether a name exits and then enter.
public void insertData(String user,String p_no,SQLiteDatabase db)
{
Cursor resultSet=db.rawQuery("select NAME from MYTABLE where NAME = '"+user+"'",null);
if(resultSet==null)
{
ContentValues cv = new ContentValues();
cv.put(NAME, user);
cv.put(PHONE, p_no);
db.insert("MYTABLE", null, cv);
}
else Toast.makeText(context,user+" already exists",Toast.LENGTH_SHORT).show();
}
But the problem is now toast comes up every time I insert meaning even if the row is unique it is not inserted.
Why resultSet is not null even when there is no such row?
It is because RawQuery never returns null cursor, and that's what your checking criteria is, so it is failing always, and trying to add new value in DB.
I am not able to find the documentation where I learned it, but I will update as soon as possible.
You can check if you have values in cursor using -
if(cursor.moveToFirst())
because it is possible to have an empty cursor. Change your check like
if(cursor.getCount() == 0)
this way, if the cursor is not null, you check if it contains something too.
Probably this is not the best way to handle duplicates, in my opinion. You should mark your column as unique, and use insertWithConflict, to decide what to do in case you have already an entry with that value
Check
if (resultset.getCount() == 0)
Also, create Name as unique key to avoid duplicates. Instead of checking it everytime.

Create Android SQL Database with a few pre populate data

I've gone through many examples here, but all seem complicated and most of them are for large data. I'm new to both Android and also SQL. What I want to do is just pre-populate my SQL database with some data.
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE restaurants (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, address TEXT, type TEXT, notes TEXT, feed TEXT, lat REAL, lon REAL);");
ContentValues cv=new ContentValues();
cv.put("name", "Hi");
cv.put("address", "There");
cv.put("type", "delivery");
cv.put("notes", "");
cv.put("feed", "");
cv.put("lat", "");
cv.put("lon", "");
getWritableDatabase().insert("restaurants", "name", cv);
}
There is no error but unfortunately no data is inserted as well. This should be very simple, please help me?
Use db.insert("restaurants", "name", cv);
Your approach is fine, inside SQLiteOpenHelper#onCreate() is the right place to put initial data since that is where you create the database in the state you like it to be.
But inside onCreate you use db.insert("restaurants", "name", cv) directly. You are not finished to create the writable database you try to get via getWritableDatabase() at that point. Not sure if that is the problem but it could be.

column is no created getting exception android

Well this is my DatabaseHelper class
public class DatabaseHelper extends SQLiteOpenHelper {
static final String dbName="demoDB";
public DatabaseHelper(Context context) {
super(context, dbName, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS players (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"playerName TEXT)";
db.execSQL(sql);
ContentValues values = new ContentValues();
values.put("playerName", "John");
db.insert("players", "playerName", values);
values.put("playerName", "George");
db.insert("players", "playerName", values);
values.put("firstName", "Marie");
db.insert("players", "playerName", values);
System.out.println("Hello");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS players");
onCreate(db);
}
}
And in my main activity this is what I do to get its data.
if (cursor!= null) {
if (cursor.moveToFirst()) {
do {
System.out.println(cursor.getString(cursor.getColumnIndexOrThrow("playerName")));
} while (cursor.moveToNext());
}
}
Why the column is not created?
and I am getting this exception.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mkyong.android/com.mkyong.android.Stats}: java.lang.IllegalArgumentException: column 'playerName' does not exist
Are you selecting anything before you interact with the cursor? Your cursor should be the result from a "Select..." SQL call, but I don't see one in your DatabaseHelper or anything in your MainActivity to indicate you are doing any sort of selection.
Also, when you are inserting values into your table , I believe the second parameter should be null [db.insert("players", null, values)]. It's intended for the nullColumnHack, which you use if you aren't entering any data into row.
nullColumnHack optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided values is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your values is empty.
Edit
Well, so far you've created a table and inserted some records. The next step would be to create basic CRUD operations (Create, Retrieve, Update, Delete), but for your case, you need to start with Retrieve.
Retrieve basically means you are reading/retrieving data from your database, so you can use it in your application. When you read the data from a DB, it gets stored in a Cursor. So, you need to:
Create a method in your database helper to read data from your database
From your main activity, call the method you created in step #1. Result is stored in a cursor.
In your main method, extract the data from the Cursor so you can use it. (Looks like you've already attempted this in your main activity).
Here is a link to a great tutorial on setting up a databse and how to create CRUD operations for your database. For now, scroll down and read up on the Retrieve operation.
http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
I would read the entire tutorial if I were you. There are lots of other helpful tips and suggestions that will be well worth the investment now. For example, creating constants in your DatabaseHelper class for the table name, database name, column name is a really good idea because sooner or later you're going to make a typo if you keep typing in all the column and table names manually. If you use variables, you'll get a compile error rather than an exception at runtime.

how to delete rows in a table on database using android sqlite3

i'm unable to delete row in a table using sqlite 3.In my code i would like to compare two
values an then delete the data in a table but it is not possible please help me.
while(authCur.moveToNext())
{
db.delete("auth_tab",authCur.getString(0)+"=?" , new String[] { user });
db.delete("auth_tab", null, null);
}
Deleting data
Once data is no longer needed it can be removed from the database with the delete() method. The delete() method expects 3 parameters, the database name, a WHERE clause, and an argument array for the WHERE clause. To delete all records from a table pass null for the WHERE clause and WHERE clause argument array.
db.delete("auth_tab", "authCur.getString(0)=?", new String[] {user);
Simply call the delete() method to remove records from the SQLite database. The delete method expects, the table name, and optionally a where clause and where clause argument replacement arrays as parameters. The where clause and argument replacement array work just as with update where ? is replaced by the values in the array.
or
public void deleteContact(long id) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(auth_tab, KEY_USER + " = ?",
new String[] { user) });
db.close();
}
WATCH more, and you tube video, how to delete.

Populate a list from a database in Android

I’m trying to query a single table database that I’ve created in my code. To the best of my knowledge the database is being created correctly. The query is supposed to be used to populate a ListView but when I try to use the resulting cursor from my query to create SimpleCursorAdapter, it crashes with: java.lang.IllegalArgumentException: column '_id' does not exist. I am assuming this can be traced to the cursor, and also the cursor seems to be empty.
The database is created in the following way within the onCreate() of my implementation of a SQLiteOpenHelper:
db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, title TEXT NOT NULL, path TEXT NOT NULL);");
And then the actual query is set up and executed in my DataHelper Class which is used to interact with the database:
public Cursor selectEntryStartsWith(String partialName , String title)
{
String where = "name LIKE '" + partialName + "%' AND title LIKE '" + title + "'";
if (title== null || title.equals("")){
where = "name LIKE '" + partialName + "%'";
}
Cursor cur = mDatabase.query(TABLE_NAME, new String[] {"_id", "name", "title"}, where, null, null, null, "name");
return cur;
}
The code that uses the cursor is as follows:
Cursor cursor = mDataHelper.selectEntryStartsWith("ex", null); //get all entries that start with "ex"
String [] from = new String [] { "name", "title" };
int [] to = new int [] { R.id.name, R.id.title };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(mContext, R.layout.listview_entry, cursor, from, to);
songList.setAdapter(adapter);
I'm using tabs to this last piece of code is from within the onActivityCreated() of a Fragment; I not that it might be better to extend a ListFragment, but I don't think this is the problem here in particularity.
Sorry in advance if I have missed an information that you may require, I've been banging my head on this problem for some time now.
Do you know the data is actually in the database? Run 'adb shell', cd to your data directory '/data/data/[app package name]/databases'. Then run sqlite3 [db file name]. Run some direct sql queries and make sure data exists.
If there is data there, rather than going right to the SimpleCursorAdapter, run some text queries in code, and see if you can access the results.
Once all of that works out, add the ListView stuff as a last step.
Some things to mention. If the user is typing in query values, you need to escape those statement values. Either use selectionArgs in the query statement:
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String)
or use my stripped-down apache commons-lang, and the StringEscapeUtils class.
http://www.touchlab.co/blog/android-mini-commons/
Another thing to consider, although if you're not having trouble, its probably not an issue. 'name' and 'title' might be tricky keywords in sql statements.
The problem was indeed the database was not set up properly, I tried another method of inserting the data i.e. using ContentValues and inserting directly into the database, as opposed to using the precompiled insert statement I was using before.
The insert method now looks like this:
public long insert(String name, String title)
{
ContentValues cv = new ContentValues();
cv.put("name", name);
cv.put("title", title);
return mDatabase.insert(TABLE_NAME, null, cv);
/* The old code was using this precompiled statement
mInsertStatement.bindString(1, name);
mInsertStatement.bindString(2, title);
return mInsertStatement.executeInsert();
*/
}

Categories

Resources