I'm trying to insert rows in my Student Table which contains two rows : ID and Name
Here is the addHandler function which is implemented in MyDBHandler class :
public void addHandler(Student student) {
ContentValues values = new ContentValues();
values.put(COLUMN_ID, student.getID());
values.put(COLUMN_NAME, student.getStudentName());
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE_NAME, null, values);
db.close();
}
The onCreate method is :-
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY ," + COLUMN_NAME + " TEXT )";
db.execSQL(CREATE_TABLE);
}
The attributes of MyDBHandler class which extends SQLiteOpenHelper :
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "studentDB.db";
public static final String TABLE_NAME = "Student";
public static final String COLUMN_ID = "StudentID";
public static final String COLUMN_NAME = "StudentName";
I have a ADD Button in my activity_main.xml file and here is the code behind :
public void add(View view){
MyDBHandler dbHandler = new MyDBHandler(this, null, null, 1);
int id = Integer.parseInt(studentIdText.getText().toString());
String name = studentNameText.getText().toString();
Student student = new Student(id, name);
dbHandler.addHandler(student);
studentIdText.setText("");
studentNameText.setText("");
}
The app is running perfectly but when i want to insert a row in the table , i get the following errors in Run Tab :
E/SQLiteLog: (1) table Student has no column named StudentID
E/SQLiteDatabase: Error inserting StudentName=yassine StudentID=10
android.database.sqlite.SQLiteException: table Student has no column named StudentID (code 1): , while compiling: INSERT INTO Student(StudentName,StudentID) VALUES (?,?)
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(table Student has no column named StudentID (code 1): , while compiling: INSERT INTO Student(StudentName,StudentID) VALUES (?,?))
#################################################################
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1093)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:670)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1607)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1479)
at com.example.test.MyDBHandler.addHandler(MyDBHandler.java:48)
at com.example.test.MainActivity.add(MainActivity.java:40)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:5246)
at android.widget.TextView.performClick(TextView.java:10566)
at android.view.View$PerformClick.run(View.java:21256)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6917)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Any recommendations ?
Your issue is very likely a mis-conception in regard to the onCreate method. That is it onCreate doesn't run every time the App is run. onCreate will only run if the database doesn't actually exist. If the database has already been created by another previous run of the App then the onCreate method is not run.
As such any changes made to the structure of the database, as typically applied in the onCreate method will not be applied.
It would appear that you have added the defnition for the StudentId column, to the code in the onCreate method, after the App has been run.
As long as you have no data that needs to be preserved (which is very likely) then the simplest solution is to do 1 of the following :-
delete or clear the App's data (via settings/Apps)
uninstall the App
and then rerun the App, the database will then be created using the code as per the modified onCreate code.
Related
I have 2 tables : registereduser, listbands. listbands has foreign key referencing registereduser(id)
I managed to create both tables in the databases, however when i create a new user the listbands fields are empty! It should have the id of registereduser.
Here is my code :
public class DatabaseHelper extends SQLiteOpenHelper {
//User table
public static final String DATABASE_NAME ="bands.db";
public static final String TABLE_USER ="registereduser";
public static final String COL_USER_ID ="BID";
public static final String COL_USER_EMAIL ="email";
public static final String COL_USER_PASS ="password";
//bands table
public static final String TABLE_LIST ="listbands";
public static final String COL_LIST_ID ="LID";
public static final String COL_LIST_FK ="BID";
public static final String COL_LIST_NAME ="name";
public DatabaseHelper(#Nullable Context context ) {
super(context, DATABASE_NAME, null , 1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("CREATE TABLE registereduser (BID INTEGER PRIMARY KEY AUTOINCREMENT, " +
"email TEXT , password TEXT )");
sqLiteDatabase.execSQL("CREATE TABLE listbands (LID INTEGER PRIMARY KEY AUTOINCREMENT ," +
"BID INTEGER NOT NULL, name TEXT, FOREIGN KEY(BID) REFERENCES registereduser(BID) )");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_USER);
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_LIST);
onCreate(sqLiteDatabase);
}
#Override
public void onOpen(SQLiteDatabase sqLiteDatabase) {
super.onOpen(sqLiteDatabase);
//enable foreign key constraints like ON UPDATE CASCADE, ON DELETE CASCADE
sqLiteDatabase.execSQL("PRAGMA foreign_keys=ON;");
}
public long addUser(String email, String password) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(" email ",email);
contentValues.put(" password ",password);
long res = db.insert("registereduser", null, contentValues);
db.close();
return res;
}
public long addList(String name) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentLists = new ContentValues();
contentLists.put(" name ",name);
long rest = db.insert("listbands", null, contentLists);
db.close();
return rest;
}
public boolean checkUser ( String email, String password){
String[] column = {COL_USER_ID};
SQLiteDatabase db = getReadableDatabase();
String choice = COL_USER_EMAIL + "=?" + " and " + COL_USER_PASS + "=?";
String[] choiceArgs = { email, password};
Cursor cursor = db.query(TABLE_USER, column, choice, choiceArgs, null, null, null);
int count = cursor.getCount();
cursor.close();
db.close();
if (count>0)
return true;
else
return false;
}
}
and this is the screenshoot that my listbands is empty:
this is screenshoot from sqlite manager
Defining a Foreign Key doesn't automatically insert data into the child table (listbands table) when a row is added to the parent table (registereduser table).
That is a Foreign Key defines a constraint (rule) saying that the value of the child column(s) must be in a row of the parent table's column(s) when inserting or updating rows in the child table.
You need to add the rows to the child table as and when required.
What the screenshot is showing is that there are now rows in the listBands table.
Currently your code has an addList method this will not work as it is as the result will be a NOT NULL constraint conflict. However, it won't fail as the exception is trapped by the insert method. However if you were to look at the value returned it would be -1 rather than 1 or greater (the id of the inserted row).
You would need to use something like :-
public long addListProper(String name, long id) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COL_LIST_FK,id);
cv.put(COL_LIST_NAME,name);
return db.insert(TABLE_LIST,null,cv);
}
to insert a listbands row.
Example
Consider the following which :-
Deletes all rows form the listbands table.
Deletes all rows from the registereduser table.
Note that as registereduser may include parents of listbands rows then listbands should be deleted first.
These two steps are just to make it so the tables are empty each time the demo is run.
Adds a user
Adds a list (that WILL NOT be added)
Adds a list using the alternative/proper insert that uses the ID of the user
Logs info regrading the id's of the inserts.
Extracts the rows from the tables into a cursor which is dumped to the log.
The code :-
mDBHlpr = new DatabaseHelper(this);
mDBHlpr.getWritableDatabase().delete(DatabaseHelper.TABLE_LIST,null,null);
mDBHlpr.getWritableDatabase().delete(DatabaseHelper.TABLE_USER,null,null);
long this_user = mDBHlpr.addUser("Fred","1234567890");
long this_list = mDBHlpr.addList("Blah"); //<<<<<<<<<< WILL NOT WORK
long alt_list = mDBHlpr.addListProper("blah blah",this_user); //<<<<<<<<< SHOULD WORK
Log.d("INSERTIFO","ID of user was " + this_user + " ID of list was " + this_list);
DatabaseUtils.dumpCursor(
mDBHlpr.getWritableDatabase().query(DatabaseHelper.TABLE_USER,null,null,null,null,null,null)
);
DatabaseUtils.dumpCursor(
mDBHlpr.getWritableDatabase().query(DatabaseHelper.TABLE_LIST,null,null,null,null,null,null)
);
Results
First in the log will be :-
2019-10-27 12:45:00.152 32338-32338/aso.so58575523foreignkeys E/SQLiteDatabase: Error inserting name =Blah
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: listbands.BID (code 1299 SQLITE_CONSTRAINT_NOTNULL)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:879)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1599)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1468)
at aso.so58575523foreignkeys.DatabaseHelper.addList(DatabaseHelper.java:76)
at aso.so58575523foreignkeys.MainActivity.onCreate(MainActivity.java:22)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
i.e. the addList has failed because BID column is null and thus the row is not inserted because of the NOT NULL constraint. Although the stack-trace is in the log the exception was trapped and thus processing continues.
The Log will then have :-
2019-10-27 12:45:00.165 D/INSERTIFO: ID of user was 3 ID of list was -1 ID of alternative list item was 2
see how the attempt to use addList resulted in an id of -1.
then :-
2019-10-27 12:45:00.165 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#561c44
2019-10-27 12:45:00.166 I/System.out: 0 {
2019-10-27 12:45:00.166 I/System.out: BID=3
2019-10-27 12:45:00.166 I/System.out: email=Fred
2019-10-27 12:45:00.166 I/System.out: password=1234567890
2019-10-27 12:45:00.166 I/System.out: }
2019-10-27 12:45:00.166 I/System.out: <<<<<
2019-10-27 12:45:00.167 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#1def12d
2019-10-27 12:45:00.167 I/System.out: 0 {
2019-10-27 12:45:00.167 I/System.out: LID=2
2019-10-27 12:45:00.167 I/System.out: BID=3
2019-10-27 12:45:00.167 I/System.out: name=blah blah
2019-10-27 12:45:00.167 I/System.out: }
2019-10-27 12:45:00.167 I/System.out: <<<<<
As can be seen the 2nd attempt (using addListProper) has added a row to listbands and there was no Foreign Key constraint conflict or the NOT NULL constraint conflict that originally stopped the row being added.
Extra
consider this line of code :-
long otheralter_list = mDBHlpr.addListProper("not blah",100); //<<<<<<< FK constraint as no user with an ID of 100.
A row is trying to be added that references a user with an id of 100 (no such user exists). The row will not be inserted (but again will not result in a failure) because of the Foreign Key constraint as no row in the registereduser table (the parent table of the Foreign Key) has 100 in the BID column (the parent column).
The result in the log would be :-
2019-10-27 13:12:39.272 32564-32564/? E/SQLiteDatabase: Error inserting BID=100 name=not blah
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:879)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1599)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1468)
at aso.so58575523foreignkeys.DatabaseHelper.addListProper(DatabaseHelper.java:86)
at aso.so58575523foreignkeys.MainActivity.onCreate(MainActivity.java:24)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Additional Re comment
So i must use CONSTRAINT in the listbands table to create a foreign key?
No you have correctly defined the Foreign Key. CONSTRAINT ???? FOREIGN KEY just gives the Constraint a name. It doesn't alter what the constraint does.
The listbands table also dont have ID even though its created as AUTOINCREMENT
No. The screen shots shows that there is no data at all in the listbands table (due to the NOT NULL constraint as explained above).
AUTOINCREMENT does very little INTEGER PRIMARY KEY is what allows an auto-generated value to be provided. Although this isn't actually correct as all that INTEGER PRIMARY KEY does is make the column an alias of the normally hidden rowid column, which is an automatically generated column for all tables except those defined using WITHOUT ROWID.
AUTOINCREMENT supplements the alias with an additional rule, that SQLite will adhere to if possible saying that the automatically generated value is greater then any previously allocated. Without AUTOINCREMENT and IF the largest possible value of the rowid (9223372036854775807) has been used then a lower value may be used. Without AUTOINCREMENT then SQLIte will instead issue an SQLITE_FULL exception.
AUTOINCREMENT uses an additional table, sqlite_sequence, to store the last assigned value of the rowid. As such inefficiencies are introduced in managing this extra table.
If AUTOINCREMENT WERE removed then there would be no noticeable difference.
I am trying to make the cart of a shopping app where I first query a cart element and from the id of a cart, list element find the corresponding meta-data related to the product by querying another table containing product information. I am able to successfully query the product list while showing the "menu" and am trying to apply the same code to the cart. Yet it tells me that the column "_id" doesn't exist. I have stuck on this for a while.
You can find the entire project on GitHub
Here are important parts of relevant files
YourCart.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_your_cart);
ContentValues values = new ContentValues();
values.put(CartContract.CartEntry._ID, 2);
values.put(CartContract.CartEntry.COLUMN_NAME_ORDERED_QUANTITY, 37);
getContentResolver().insert(CartContract.CartEntry.CONTENT_URI, values);
String[] projection = {
CartContract.CartEntry._ID,
CartContract.CartEntry.COLUMN_NAME_ORDERED_QUANTITY
};
//gets the entire cart
cart = getContentResolver().query(CartContract.CartEntry.CONTENT_URI, projection, null, null, null);
ListView cartList = findViewById(R.id.CartListView);
cartList.setAdapter(new cartAdapter(YourCart.this, cart));
}
// Following is part of cartAdapter
#Override
public void bindView(View view, Context context, Cursor cart) {
prodName = view.findViewById(R.id.cartListElementProductNameTextView);
prodPrice = view.findViewById(R.id.cartListElementProductPriceTextView);
//Projection is just the name of the columns we would like to receive
String[] projection = {
ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_THUMBNAIL,
ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_NAME,
ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_PRICE
};
Integer ui = cart.getInt(cart.getColumnIndexOrThrow(CartContract.CartEntry._ID));
String[] hoho = {ui.toString()};
Cursor productCursor = getContentResolver().query(ProductListContract.ProductEntry.CONTENT_URI, projection, ProductListContract.ProductEntry._ID, hoho, null);
prodName.setText(productCursor.getInt(productCursor.getColumnIndexOrThrow(ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_NAME)));
ui = productCursor.getInt(productCursor.getColumnIndexOrThrow(ProductListContract.ProductEntry.COLUMN_NAME_PRODUCT_PRICE));
prodPrice.setText(ui.toString());
productCursor.close();
}
I'm pretty sure the column gets created when the table is created as can be seen here from an excerpt from the Database Helper
public static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + TABLE_NAME + " ( " +
_ID + " INTEGER NON NULL, " +
COLUMN_NAME_ORDERED_QUANTITY + " INTEGER)";
Finally here is the log of the crash. The app crashes as soon as the YourCart activity is launched
03-16 09:50:30.987 11672-11672/com.example.tanmay.shoppingapp E/SQLiteLog: (1) table cart has no column named _id
03-16 09:50:30.991 11672-11672/com.example.tanmay.shoppingapp E/SQLiteDatabase: Error inserting quantity=37 _id=2
android.database.sqlite.SQLiteException: table cart has no column named _id (code 1): , while compiling: INSERT INTO cart(quantity,_id) VALUES (?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1472)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1343)
at com.example.tanmay.shoppingapp.DataSet.DataProvider.insertCart(DataProvider.java:169)
at com.example.tanmay.shoppingapp.DataSet.DataProvider.insert(DataProvider.java:155)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:264)
at android.content.ContentResolver.insert(ContentResolver.java:1279)
at com.example.tanmay.shoppingapp.YourCart.onCreate(YourCart.java:34)
at android.app.Activity.performCreate(Activity.java:6684)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2652)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2766)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
03-16 09:50:30.991 11672-11672/com.example.tanmay.shoppingapp E/com.whatever.tag: Failed to insert row for content://com.example.tanmay.shoppingapp/cart
03-16 09:50:30.992 11672-11672/com.example.tanmay.shoppingapp E/SQLiteLog: (1) no such column: _id
03-16 09:50:30.994 11672-11672/com.example.tanmay.shoppingapp D/AndroidRuntime: Shutting down VM
03-16 09:50:30.996 11672-11672/com.example.tanmay.shoppingapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tanmay.shoppingapp, PID: 11672
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tanmay.shoppingapp/com.example.tanmay.shoppingapp.YourCart}: android.database.sqlite.SQLiteException: no such column: _id (code 1): , while compiling: SELECT _id, quantity FROM cart
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2699)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2766)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
Caused by: android.database.sqlite.SQLiteException: no such column: _id (code 1): , while compiling: SELECT _id, quantity FROM cart
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1318)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1165)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1036)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1204)
at com.example.tanmay.shoppingapp.DataSet.DataProvider.query(DataProvider.java:92)
at android.content.ContentProvider.query(ContentProvider.java:1020)
at android.content.ContentProvider$Transport.query(ContentProvider.java:239)
at android.content.ContentResolver.query(ContentResolver.java:534)
at android.content.ContentResolver.query(ContentResolver.java:475)
at com.example.tanmay.shoppingapp.YourCart.onCreate(YourCart.java:44)
at android.app.Activity.performCreate(Activity.java:6684)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2652)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2766)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
For some reason the table does not contain the column named _id. However, it is not because of the SQL, even though the SQL likely does not do what you wish.
More specifically the use of INTEGER NON(instead of NOT)NULL will rather than add the NOT NULL constraint, it will give the column a column_type of INTEGER NON which will equate, as it contains INT, to a column-type (affinity) of INTEGER.
As an example (this utilises the logDatabaseInfo to be found here) which with the SQL as :-
CREATE TABLE cart (_ID INTEGER NON NULL, quantity INTEGER)
Shows :-
D/SQLITE_CSU: DatabaseList Row 1 Name=main File=/data/data/soupd.so49313202updatefailed/databases/mydb
D/SQLITE_CSU: Database Version = 1
D/SQLITE_CSU: Table Name = android_metadata Created Using = CREATE TABLE android_metadata (locale TEXT)
D/SQLITE_CSU: Table = android_metadata ColumnName = locale ColumnType = TEXT Default Value = null PRIMARY KEY SEQUENCE = 0
D/SQLITE_CSU: Table Name = cart Created Using = CREATE TABLE cart (_ID INTEGER NON NULL, quantity INTEGER)
D/SQLITE_CSU: Table = cart ColumnName = _ID ColumnType = INTEGER NON Default Value = null PRIMARY KEY SEQUENCE = 0
D/SQLITE_CSU: Table = cart ColumnName = quantity ColumnType = INTEGER Default Value = null PRIMARY KEY SEQUENCE = 0
Table = cart ColumnName = _ID ColumnType = INTEGER NON Default Value = null being the pertinent information.
The SQL should likely be :-
CREATE TABLE cart (_ID INTEGER NOT NULL, quantity INTEGER)
Note normally _id/_ID is used for a column that holds a unique identifier that is automatically generated by SQLite, and thus
typically you would have _ID INTEGER PRIMARY KEY for the column
definition. Coding this and not providing a value for the _id will
result in the unique identifier being generated by SQLite (typically
1,2,3,4.....).
Note I haven't shown this in the SQL below because you would need to look at inserting without the id.
The Likely Real Issue
The real issue is elsewhere but is very likely due to the DatabaseHelper's onCreate method not having been called. It has likely been called once as the database exists. So the most likely issue is that the table structure has been changed but the database hasn't been deleted.
More specifically the onCreate method is only invoked (automatically) once when the database is created.
The Likely Fix
The likely fix is that the database should be deleted and then the App rerun.
- You can delete the database by deleting the App's data
- or by uninstalling the App.
- I'd suggest changing the SQL as shown above.
try replacing your create SQL_CREATE_ENTRIES statement by this,
public static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + TABLE_NAME + " ( " +
_ID + " INTEGER NOT NULL, " +
COLUMN_NAME_ORDERED_QUANTITY + " INTEGER)";
your query has invalid key word which is "NON" in _ID column.
I keep getting this error "table places has no clumn named description_place" still pretty new to android so no clue why this happens, can anyone spot the error?
This is my Database class:
public class BDManager {
private static final String TABLE_NAME = "places";
public static final String KEY_ID_PLACE = "_id";
public static final String KEY_NOM_PLACE = "nom_place";
public static final String KEY_TYPE_PLACE = "type_place";
public static final String KEY_ADDRESS_PLACE = "address_place";
public static final String KEY_DESCRIPTION_PLACE = "description_place";
public static final String CREATE_TABLE_PLACES = "CREATE TABLE "
+ TABLE_NAME + "("
+ KEY_ID_PLACE + " INTEGER PRIMARY KEY, "
+ KEY_NOM_PLACE +" TEXT, "
+ KEY_TYPE_PLACE +" TEXT, "
+ KEY_ADDRESS_PLACE +" TEXT, "
+ KEY_DESCRIPTION_PLACE +" TEXT);";
private MySQLite maBaseSQLite;
private SQLiteDatabase db;
public BDManager(Context context){
maBaseSQLite = MySQLite.getInstance(context);
}
public void open() {
db = maBaseSQLite.getWritableDatabase();
}
public void close() {
db.close();
}
public long addPlace(BD place){
ContentValues values = new ContentValues();
values.put(KEY_NOM_PLACE, place.getNom_place());
values.put(KEY_TYPE_PLACE, place.getType_place());
values.put(KEY_ADDRESS_PLACE, place.getAddress_place());
values.put(KEY_DESCRIPTION_PLACE, place.getDescription_place());
return db.insert(TABLE_NAME,null,values);
}
public int modPlace(BD place){
ContentValues values = new ContentValues();
values.put(KEY_NOM_PLACE, place.getNom_place());
values.put(KEY_TYPE_PLACE, place.getType_place());
values.put(KEY_ADDRESS_PLACE, place.getAddress_place());
values.put(KEY_DESCRIPTION_PLACE, place.getDescription_place());
String where = KEY_ID_PLACE+" = ?";
String[] whereArgs = {place.getId_place()+""};
return db.update(TABLE_NAME, values, where, whereArgs);
}
public BD getPlace(int id){
BD p = new BD("","","","");
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+KEY_ID_PLACE+"="+id, null);
if (c.moveToFirst()){
p.setId_place(c.getInt(c.getColumnIndex(KEY_ID_PLACE)));
p.setNom_place(c.getString(c.getColumnIndex(KEY_NOM_PLACE)));
p.setType_place(c.getString(c.getColumnIndex(KEY_TYPE_PLACE)));
p.setAddress_place(c.getString(c.getColumnIndex(KEY_ADDRESS_PLACE)));
p.setDescription_place(c.getString(c.getColumnIndex(KEY_DESCRIPTION_PLACE)));
c.close();
}
return p;
}
public Cursor getPlaces(){
return db.rawQuery("SELECT * FROM "+TABLE_NAME, null);
}
}
It makes the error when I try tu save a place with the addplace function here :
public void savePlace(View view) {
final EditText name = (EditText) findViewById(R.id.NomPlace);
final Spinner type = (Spinner) findViewById(R.id.TypePlace);
final EditText address = (EditText) findViewById(R.id.AdressePlace);
final EditText description = (EditText) findViewById(R.id.DescriptionPlace);
BDManager sav = new BDManager(this);
sav.open();
sav.addPlace(new BD(name.getText().toString() ,type.getSelectedItem().toString() , address.getText().toString(),description.getText().toString()));
sav.close();
name.setText("");
type.setSelection(0);
address.setText("");
description.setText("");
}
Here is the complete error :
table places has no column named description_place
Error inserting description_place= nom_place=fyeyryfu address_place=dure type_place=Default
android.database.sqlite.SQLiteException: table places has no column named description_place (code 1): , while compiling: INSERT INTO places(description_place,nom_place,address_place,type_place) VALUES (?,?,?,?)
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(table places has no column named description_place (code 1): , while compiling: INSERT INTO places(description_place,nom_place,address_place,type_place) VALUES (?,?,?,?))
#################################################################
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1093)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:670)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1607)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1479)
at com.myfavoriteplaces.myfavoriteplaces.BDManager.addPlace(BDManager.java:49)
at com.myfavoriteplaces.myfavoriteplaces.SavePlaces.savePlace(SavePlaces.java:124)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:5076)
at android.view.View$PerformClick.run(View.java:20279)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
Can someone help me please ?
Dude i was gonna ask for a magic wand but then.... eureka (no nudity like the greek dude is involved :-) ) I once had similar problem
A SINGLE SPACE BETWEEN THE WORD "TEXT AND THE BRACE IS NEEDED
KEY_DESCRIPTION_PLACE +" TEXT );";
I trust AN UPVOTE IS THE LEAST U CAN OFFER
mostly when a missing column error is crushing android success dream... its the cause of typing error.
Heil Android!!!
when you change database information you need to Drop table in OnOpdate()
if you want shere your onCreate and OnUpdate (MySQLite) code and i fix it
The error I'm getting is SQLiteException: near ",": syntax error (code 1), and I cant figure where my mistake is.
I´ve read some other questions with the same error and the answer they give is that it's a simple syntax error with a missing comma. However I've checked again and that doesn't seem to be my problem. I've included the code below.
public static final String prospectos="RegProspectos.db";
public static final int dbversion = 1;
public static final String tabla_prospectos="prospectos";
public static final String cm_NomProspec="NomProspec";
public static final String cm_ApProspec="ApProspec";
public static final String cm_AmProspec="AmProspec";
public static final String cm_RfcProspec="RfcProspec";
public static final String cm_TelCasa="TelCasa";
public static final String cm_TelOficina="TelOficina";
public adminProspec(Context context)
{super(context,prospectos, null, dbversion);}
#Override
public void onCreate(SQLiteDatabase db) {
final String crea_tabla=
"CREATE TABLE "+tabla_prospectos+"("
+cm_NomProspec+ " TEXT,"
+cm_ApProspec+ " TEXT,"
+cm_AmProspec+ " TEXT,"
+cm_RfcProspec + " TEXT,"
+cm_TelCasa+ " TEXT,"
+cm_TelOficina+ " TEXT,"
+cm_UsrActReg+ " TEXT "+")";
db.execSQL(crea_tabla); }
Here is my logcat output:
06-30 11:15:18.083: E/SQLiteDatabase(1867): Error inserting = escobedo=escobedo gurrola=gurrola cesar=cesar Guec=Guec
06-30 11:15:18.083: E/SQLiteDatabase(1867): android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: INSERT INTO prospectos(,escobedo,gurrola,cesar,Guec) VALUES (?,?,?,?,?)
06-30 11:15:18.083: E/SQLiteDatabase(1867): at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
06-30 11:15:18.083: E/SQLiteDatabase(1867): at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
thank you so much like you said the error where in the insert method,
the problem i think, was that I were trying to insert values instead of fields correct me if I'm wrong, that's simple but i don't know how to explain it...
...sNomProspec.getText().toString();
...sApProspec.getText().toString();
...sAmProspec.getText().toString()
altaProspecto.put(NomProspec, NomProspec);
altaProspecto.put(ApProspec, ApProspec);
altaProspecto.put(AmProspec, AmProspec);
altaProspecto.put("NomProspec", sNomProspec.getText().toString());
altaProspecto.put("ApProspec", sApProspec.getText().toString());
altaProspecto.put("AmProspec", sAmProspec.getText().toString());
I just added the quotes and changed I corrected and now it works thanks a lot =D
06-30 11:15:18.083: E/SQLiteDatabase(1867): android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: INSERT INTO prospectos(,escobedo,gurrola,cesar,Guec) VALUES (?,?,?,?,?)
This error is about an Insert that you do somewhere... You put a comma inside an Insert so your Insert should be like this :
INSERT INTO prospectos(escobedo,gurrola,cesar,Guec) VALUES (?,?,?,?,?)
Other issue that I'm seeing is that in your Insert you put 4 fields and on your values you put 5, you have to put the same values as fields you put. (I guess your ? values are something that you don't want to show to us, if it's not, you can't pass a ? to an Insert).
See SQLite - INSERT Query to know more about INSERT INTO.
You should use ContentValues to insert your data:
Example:
ContentValues contentValues = new ContentValues();
contentValues.put(cm_NomProspec, "nomProstect value");
contentValues.put(cm_ApProspec, "Prostect value");
contentValues.put(cm_RfcProspec, "pfProstect value");
database.insert(tabla_prospectos, null, contentValues);
bd.close();
Toast.makeText(this, "Se Cargaron los Datos del Prospecto,",+ Toast.LENGTH_LONG).show();
I have a problem with SQLite in android , I tried a simple insert in a table but I have an exception and in the exception I read this :
INSERT INTO Biblio(Auteur,Image,Livre) VALUES (?,?,?)
this is my method :
public void AddBook(Bibliothèque bibliothèque)
{
SQLiteDatabase db=this.getWritableDatabase();
//this.open();
ContentValues values=new ContentValues();
values.put(KEY_Auteur,bibliothèque.getNomAuteur());
values.put(KEY_Livre,bibliothèque.getNomLivre());
values.put(Key_photo,bibliothèque.geturiimage().toString());
db.insert("Biblio",null,values);
db.close();
}
and this is my variables:
private static final String TABLE_Nom = "Biblio";
private static final String KEY_ID = "id";
private static final String KEY_Auteur = "Auteur";
private static final String KEY_Livre = "Livre";
private static final String Key_photo="Image";
the problem I don't know why but db.insert invert beetween Image and Livre and because of that I have an exception and I don't know why the value that I insert are ? ? ? in debug I can see that the value are correct ! . normaly the true expression must be :
INSERT INTO Biblio(Auteur,Livre,Image) VALUES (cc,test,(uri of picture))
this is the entire exception :
2927-2927/com.example.myapplication4.app E/SQLiteLog﹕ (1) table Biblio has no column named Livre
05-15 02:53:54.436 2927-2927/com.example.myapplication4.app E/SQLiteDatabase﹕ Error inserting Auteur=gsopfkgop Image=content://media/external/images/media/10 Livre=fhoksgkp
android.database.sqlite.SQLiteException: table Biblio has no column named Livre (code 1): , while compiling: INSERT INTO Biblio(Auteur,Image,Livre) VALUES (?,?,?)
USE This Query to Create Table.
db.execSQL
("CREATE TABLE Biblio (id INTEGER PRIMARY KEY AUTOINCREMENT ,Auteur TEXT,Livre TEXT,Image TEXT)");
then You have to insert record using Below code:
public void AddBook(Bibliothèque bibliothèque)
{
SQLiteDatabase db=this.getWritableDatabase();
//this.open();
ContentValues values=new ContentValues();
values.put(Auteur,bibliothèque.getNomAuteur());
values.put(Livre,bibliothèque.getNomLivre());
values.put(Image,bibliothèque.geturiimage().toString());
db.insert("Biblio",null,values);
db.close();
}
I hope its useful to you..
2927-2927/com.example.myapplication4.app E/SQLiteLog﹕ (1) table Biblio has no column named Livre
Your table doesn't have a column named Livre, either you have a spelling mistake here, in your table creation code, or you haven't defined a column named Livre.
You should try to reinstall your app?
Also, if your db schema has been changed after your app installed in your test device, you have to increase db version parameter to invoke onUpdate() method or reinstall your app to invoke onCreate().