Error in Inserting values to Database - android

I am creating a simple Database to add the values of product. While adding the entries in database I am getting an error in Logcat and the program get stop there and then.
I am not clear with the error but its something related to insertion of data or in query I have written. I tried all possible alternatives I could.
Program Code is :
DataBase.java
public class DataBase extends SQLiteOpenHelper
{
public DataBase(Context context) {
super(context, CreateTable.DB_NAME, null, CreateTable.DB_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String create = "Create Table " + CreateTable.TABLE_NAME + "( " + CreateTable.KEY_ID
+ " INTEGER PRIMARY KEY," + CreateTable.KEY_NAME + " TEXT,"
+ CreateTable.KEY_PRICE + " REAL)";
db.execSQL(create);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
public void addProduct(Product p)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues c = new ContentValues();
c.put(CreateTable.KEY_NAME, p.getName());
c.put(CreateTable.KEY_PRICE, p.getPrice());
db.insert(CreateTable.TABLE_NAME, null, c);
db.close();
}
}
EnterDeatils.java
public class EnterDeatils extends Activity {
EditText name;
EditText price;
Button done;
int id = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.enter_deatils);
name = (EditText) findViewById(R.id.edtname);
price = (EditText) findViewById(R.id.edtprice);
done = (Button) findViewById(R.id.btndone);
done.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Product p = new Product();
p.setId(id);
p.setName(name.getText().toString());
p.setPrice(Float.valueOf(price.getText().toString()));
DataBase d = new DataBase(EnterDeatils.this);
d.addProduct(p);
}
});
}
}
LogCat Error:
01-12 23:06:52.343: E/Database(382): Error inserting pPrice=12.0 pName=ds
01-12 23:06:52.343: E/Database(382): android.database.sqlite.SQLiteException: table Books has no column named pPrice: , while compiling: INSERT INTO Books(pPrice, pName) VALUES(?, ?);
Requesting you guys to just help me to identify the error.
Thanks in Advance.

SQLiteOpenHelper onCreate() is only called if the database file does not exist. If you modify the SQL in onCreate(), you'll have to ensure the database file is updated.
Two approaches:
Delete the old version of the database. Uninstall is one way to do this. This way the database is created with whatever code you currently have in onCreate(). This is often the simplest way during app development.
Bump up the database version number you pass to SQLiteOpenHelper superclass. If this number is different from the version number stored in the database file, onUpgrade() or onDowngrade() is called, and you can update the database schema. This is the preferred way when you already have released versions out so your users can preserve their data when updating your app.

Delete your database from terminal
adb shell
cd /data/data/com.example.applicationname/databases
rm *
First you created table Books with x number of columns but pPrice column was not included in that create table query. Later on you added this column name to your create table query.
That's why this problem happened.
Try to delete the database. It will delete the old database from application and when you re start new database will be created.
onCreate() is only called if your database DOES NOT exist

Seems that your database was created without column KEY_PRICE.
After that you have altered your code adding column KEY_PRICE to String create.
If this is true you must increment database version in order it be created again:
Change:
CreateTable.DB_VERSION = 1;
To
CreateTable.DB_VERSION = 2;
As laalto suggested change onUpgrade
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + CreateTable.TABLE_NAME);
onCreate(db);
}

Check if you are missing some space. I had same problem , and solved with adding space...

Related

SQLite problem of no such column when trying to insert

I use Sqlite and I have the following DB , I am developing an application for women which it should contain a login and sign up . I had problems in the database like "no such column"
DataBase
public class DB_MJG extends SQLiteOpenHelper {
public static final String name ="dataB.db";
public static final int version =1;
//Les atts de la table FEMME
public static final String table_Femme ="Femme";
public static final String ID_F = "id";
public static final String NOM_F ="nom";
public static final String PRENOM_F="prenom";
public static final String PSEUDO="pseudo";
public static final String MDP="mdp";
public static final String GRP_F="grpSang";
public static final String AGE_F="age";
public static final String POIDS="poids";
public DB_MJG( Context context) {
super(context, name, null, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE_FEMME = "CREATE TABLE " + table_Femme + "(
"+ID_F+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+NOM_F+" TEXT, "+PRENOM_F+" TEXT " + ")";
db.execSQL(CREATE_TABLE_FEMME);
System.out.println("table femme crée");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS "+table_Femme);
db.execSQL("DROP TABLE IF EXISTS "+table_Enfant);
}
//insérer dans la table FEMME
public void insertFemme(Femme f)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues vals = new ContentValues();
vals.put(NOM_F,f.getNom());
vals.put(PRENOM_F,f.getPrenom());
db.insert(table_Femme,null,vals);
db.close();
}
public ArrayList getFemme()
{
ArrayList<Femme> femmes = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM " +table_Femme, null);
while(c.moveToNext()){
Femme f = new Femme(c.getString(1),c.getString(2));
femmes.add(f);
}
return femmes;
}
}
Launcher Activity
public class MainActivity extends AppCompatActivity {
DB_MJG db = new DB_MJG(this);
SQLiteDatabase database ;
String s = "";
private Button log,sign;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
database = openOrCreateDatabase(db.name, Context.MODE_PRIVATE, null) ;
db.insertFemme(new Femme("sara","sara"));
ArrayList<Femme> femmes = db.getFemme();
TextView textView= (TextView) findViewById(R.id.textView13);
for(Femme f : femmes){
String ch = "Nom :" +f.getNom() + " Prenom : "
+f.getPrenom()+"\n";
s = s +ch;
}
textView.setText(s);
}
Error
E/SQLiteLog: (1) table Femme has no column named nom
E/SQLiteDatabase: Error inserting nom=sara prenom=sara
android.database.sqlite.SQLiteException: table Femme has no column named
nom (code 1 SQLITE_ERROR): , while compiling: INSERT INTO
Femme(nom,prenom) VALUES (?,?)
at
android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native
Method)
When I compile,it says no such column. I have defined the nom column. The database has the nom that I am trying to use for inserting but it doesn't work.
The primary issue you have is that the database helper's onCreate method is only called when the database is created, which is once in it's lifetime.
As such if any changes are made to the structure (schema) by amending the create table SQL, as used in the onCreate method, they will not be reflected unless the database is deleted or that the onCreate method is invoked some other way.
Often such changes, as least when developing the app, are applied by first doing one of the following :-
Deleting the App's data (this deletes the database, so onCreate is automatically called).
Uninstalling the App (and as a result deletes the App's data).
IF the onUpgrade method is written to drop the changed table(s) and recreate the tables (often/generally by calling the onCreate method)
After doing one of the above, rerunning the App will then result in the structure change being applied.
Note the above will result in the loss of existing data and IS NOT SUITABLE for an App that has been deployed.
In your case if using option 3, the onUpgrade method needs to include the creation of the table(s) after they have been dropped as it only drops the tables.
You code in the MainActivity is also overly complex in that it utilises opening the database without using the SQLiteOpenHelper to open the database but rather opens it using the SQLiteDatabase openOrCreate method (which doesn't result in the SQLiteOpenHelper's (DB_MJG is a subclass of SQLiteOpenHelper) onCreate method being called). However, by a quirk/luck, when you do start to use the instance of DB_MJG, namely db, as the instance was created before openOrCreate method, it actually goes on to call the onCreat method.
However, it would be much simpler, to just use one method to open the database.
As such I'd suggest implementing using just the DB_MJG DatabseHelper.
Fix
The essential fix, is to introduce the changed structure. So one of the 3, above should be taken.
if using 3. then amending the onUpgrade method to call the onCreate method and then increasing the version number would be required. That is the onUpgrade method could be :-
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS "+table_Femme);
db.execSQL("DROP TABLE IF EXISTS "+table_Enfant);
onCreate(db); //<<<<<<<<<< ADDED so that onUpgrade creates the tables after they have been dropped
}
Additional/Recommended
Close Cursor
in DB_MJG.java the getFemme method leaves the Cursor open. This can result in a too many open databases or cursors excpetion so it is suggested that the line :-
c.close();
is added to the getFemme method, so it becomes :-
public ArrayList getFemme()
{
ArrayList<Femme> femmes = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM " +table_Femme, null);
while(c.moveToNext()){
femmes.add(new Femme(c.getString(c.getColumnIndex(NOM_F)),c.getString(c.getColumnIndex(PRENOM_F))));
}
c.close(); //<<<<<<<<<< should always close a cursor when finished with it
return femmes;
}
Note the above also does away with the need for the intermediate Femme object f.
Use DB_MJG to open the database
There is no need to openOrCreate the database when using a subclass of SQliteOpenHelper as it will do this. So MainActivity.java could be :-
public class MainActivity extends AppCompatActivity {
DB_MJG db; // Only declare the DB_MJG object.
private Button log,sign;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DB_MJG(this);
db.insertFemme(new Femme("sara","sara"));
ArrayList<Femme> femmes = db.getFemme();
TextView textView= (TextView) findViewById(R.id.textView13);
StringBuilder sb = new StringBuilder(); //<<<<<<<<<< ADDED - Use StringBuilder in a loop
for(Femme f : femmes){
sb.append("Nom: ").append(f.getNom()).append(" Prenom: ").append(f.getPrenom());
}
textView.setText(sb.toString());
}
}
Note that the above should be changed at the same time or after the fix has been applied.
Instead of concatenating Strings in a loop a StringBuilder has been used. See -Why to use StringBuffer in Java instead of the string concatenation operator

Android SQLIte No Such Table Error - On Click

Good afternoon,
I am trying to create a database for a monthly assessment form as part of my, it will be the second table of my application first being login details.
I followed the same format but am getting "NO SUCH TABLE" followed by my variable name.
I was hoping this issue had been seen before and how it could be eradicated.
Uninstall the old application on your phone completely and run your project again. This error is happening because the onCreate() method of the SQLiteOpenHelper derived class is called only once. For it to be called again, either you derive another custom class from SQLiteOpenHelper and define your second table there, or you uninstall the old APK and re-run the project from the IDE. When you run it again, both tables will be created.
Make database like this :
public class Data_Base extends SQLiteOpenHelper {
public static final String dbname = "suri29";
public static final Integer dbversion = 1;
public static final String dbtable = "user";
public static final String name = "username";
public static final String column_id = "_id";
public Data_Base(Context context) {
super(context, dbname, null, dbversion);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("create table " + dbtable + " (" + column_id
+ " integer primary key autoincrement, username text not null)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVesion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("drop table if exists " + dbtable);
onCreate(db);
}
Without digging deeper into you code, I have some advices for you that going to make you avoid tons of mistakes:
1)Use SQLite Database Helper for creating, inserting, deleting you data from the database...Follow this tutorial
2)Rewriting your columns name in each query is a very bad practice. Initialize them at the beginning of your class as final static string and use this variable whenever you need it.
private final static String COL_COMMENTS = "COMMENTS";
3)Try and catch all your database transactions with logging to avoid crashes.
try{
//Database transaction
}
catch(Exception e){
e.printstacktrace();
}
4)Uninstall the application and install it again after adding any new table.

Android cannot insert into SQLite3 DB

I am trying to insert some data into and SQLite DB on android, but the code below just does not work. Can anyone spot the issue.
db = this.openOrCreateDatabase("data_7.db", 0, null);
db.execSQL("CREATE TABLE IF NOT EXISTS 'group' (my_id TEXT NOT NULL, my_key TEXT NOT NULL)");
db.execSQL("INSERT INTO 'group' (my_id, my_key) VALUES ('abc', '123')");
db.close();
After running the code I extracted the SQLite file off the emulator and opened it using an SQLite GUI viewer, the table was created but no data was inserted.
Note:
I have searched through this site all day and could not find a
suitable answer to this issue
I would like to do this without the aid of helper methods like
.insert(). ie. I need to user pure SQL
Try out this way:
"INSERT INTO group (my_id, my_key) " + "VALUES ('" + field_one + "', '" + field_two + "')";
you have to create the table in the method onCreate() that is found on the Dababase class that you have to build like this:
public class Database extends SQLiteOpenHelper
{
public static final String DB_NAME="YourDBName";
public static final int VERSION=1;
Context context=null;
public Database(Context context)
{
super(context, DB_NAME, null, VERSION);
this.context=context;
}
#Override
public void onCreate(SQLiteDatabase db)
{
try
{
String sql="CREATE TABLE group(my_id TEXT NOT NULL PRIMARY KEY, my_key TEXT NOT NULL)";
String insert="INSERT INTO group VALUES('abc','123');";
db.execSQL(sql);
db.execSQL(insert);
}
catch(Exception e)
{
Log.d("Exception", e.toString());
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS group");
onCreate(db);
}
}
Make sure that the old database is deleted or change the version to 2 in order to execute the query.
If you need to execute this query you need to write:
Database db=new Database();
SQLiteDatabasse read=db.getReadableDatabase();

Check for the existence of database in Android [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to check existing database before creating new database on Android 2.2?
I have an app which check the existence of database in the start up. If not exits create a new one and if there then access the database. Can you please tell me how to check the existence of db(SQlite)?
Android helps a lot developpers to manage a database.
You should have a class like this (a single table with only 1 column) :
public class MyDBOpenHelper extends SQLiteOpenHelper {
private static final String queryCreationBdd = "CREATE TABLE partie (id INTEGER PRIMARY KEY)";
public MyDBOpenHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(queryCreationBdd);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE partie;");
db.execSQL("DELETE FROM sqlite_sequence"); //table which contains the next incremented key value
onCreate(db);
}
}
Then you simply do this :
MyDBOpenHelper databaseHelper = new MyDBOpenHelper(context, "dbname.db", null, 1);
SQLiteDatabase bdd = databaseHelper .getWritableDatabase();
If necessary, Android will create the database (call the onCreate method) or give you the one that already exists. The fourth parameter is the version of the database. If the currently created database is not the latest version, onUpgrade will be called.
EDIT : The database path will be something like this :
/data/data/fr.mathis.application/databases/dbname.db
Take a look at query-if-android-database-exists
Open your database in try block with path of the databse like:
try{
SQLiteDatabase dbe = SQLiteDatabase.openDatabase("/data/data/bangla.rana.fahim/databases/dictionary", null,0);
Log.d("opendb","EXIST");
dbe.close();
}
if an exception occurs then database doesn't exist so create it:
catch(SQLiteException e){
Log.d("opendb","NOT EXIST");
SQLiteDatabase db = openOrCreateDatabase("dictionary", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS LIST(wlist varchar);");
db.execSQL("INSERT INTO LIST VALUES('খবর');");
db.execSQL("INSERT INTO LIST VALUES('কবর');"); //whatever you want
db.close();
}
that's it you are done :)
I use a boolean flag which is set to true when onCreate of SQLiteOpenHelper is invoked. You can find my full code here

Storing application database schema

In example apps database is in most cases single table, so db schema is stored in static variable.
Storing large schema in seperate file is more friendly for me.
How can I do that? I thought about using resources (R.strings.db_schema) but probably there is a better way.
Could somebody give me any advice?
You could put the schema data in a raw file under res/raw. Then you can just load and parse that file the first time.
The way I do is to have a class per table, named after the table with "Table" suffix (e.g. PlayerTable or EventTable).
These classes contain all the static variable for the table name and all the field names, and they also contain two static methods:
public static void onCreate(SQLiteDatabase database)
public static void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion)
So that my SQLiteOpenHelper can just call all of them, without having hundreds of static variables with all the fields and create queries. E.g:
#Override
public void onCreate(SQLiteDatabase database) {
PlayerTable.onCreate(database);
EventTables.onCreate(database);
..... any other table you have .....
}
This class is then injected into all my data access objects (select / update / insert queries). For them I have dedicated classes that contain all my methods, by functionality (e.g. EventHandlingDAO for all the queries that deal with event handling).
And finally, theses DAO are injected into the activities that need them, when needed.
EDIT: A few more details about my code:
My main objects are the DAO (data access objects), in which I have methods like:
// in EventHandlingDAO:
public void addEvent(Event event) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
try {
database.execSQL("INSERT INTO " + EventTable.EVENT_TABLE_NAME + " (...."); // list of fields and values
} finally {
database.close();
}
}
public List<Event> getAllEvents() {
final List<Event> result = new ArrayList<Event>();
SQLiteDatabase database = databaseHelper.getReadableDatabase();
try {
final Cursor cursor = database.rawQuery("SELECT " + EventTable.KEY_NAME + ", " + EventTable.KEY_DATE_AS_STRING + " FROM " + EventTable.TABLE_NAME, null);
cursor.moveToFirst();
// ... rest of the logic, that iterates over the cursor, creates Event objects from the cursor columns and add them to the result list
return result;
} finally {
database.close();
}
}
So in that DAO, I have my databaseHelper object, which instanciates my class that extends SQLiteOpenHelper with the methods I talked about above.
And of course, I have interfaces to all my DAO, so that I can inject a Stub or mocked implementation in my tests (or experiment with different implementations if I want to try another solution based on SharedPreference for example)
And the code for my PlayerTable table:
public static void onCreate(SQLiteDatabase database) {
database.execSQL(TABLE_CREATE); // TABLE_CREATE is my "CREATE TABLE..." query
}
public static void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
// A bit blunt, that destroys the data unfortunately, I'll think about doing something more clever later ;)
database.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(database);
}

Categories

Resources