Unable to add data to SQLite table in android - android

I'm working on a simple SQLite CRUD application and I want to add data to manually created database in SQLite. But when I'm adding data, the app stops and shows the below error message
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sqlitecrudexample, PID: 14124
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: employees.id (code 1299 SQLITE_CONSTRAINT_NOTNULL)
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:890)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:756)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:66)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1920)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1897)
at com.example.sqlitecrudexample.MainActivity.addEmployee(MainActivity.kt:70)
at com.example.sqlitecrudexample.MainActivity.access$addEmployee(MainActivity.kt:13)
at com.example.sqlitecrudexample.MainActivity$onCreate$1.onClick(MainActivity.kt:30)
at android.view.View.performClick(View.java:7448)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I/Process: Sending signal. PID: 14124 SIG: 9
Here is my code for creating and adding data to the table
private fun addEmployee(){
var name:String = editTextName.text.toString().trim()
var salary:String = editTextSalary.text.toString().trim()
var dept = spinnerDepartment.selectedItem.toString()
var calendar = Calendar.getInstance()
var simpleDateFormat = SimpleDateFormat("yyyy-mm-dd hh:mm:ss")
var joiningDate = simpleDateFormat.format(calendar.time)
if(inputsAreCorrect(name,salary)){
val insertSQL = """
INSERT INTO employees
(name, department, joiningdate, salary)
VALUES
(?, ?, ?, ?);
""".trimIndent()
mDatabase.execSQL(insertSQL, arrayOf(name, dept, joiningDate, salary))
Toast.makeText(this,"Employee Added Successfully",Toast.LENGTH_SHORT).show()
}
}
private fun createEmployeeTable() {
mDatabase.execSQL(
"""CREATE TABLE IF NOT EXISTS employees (
id int PRIMARY KEY AUTOINCREMENT NOT NULL,
name varchar(200) NOT NULL,
department varchar(200) NOT NULL,
joiningdate datetime NOT NULL,
salary double NOT NULL
);"""
)
}
And this is my data class
data class Employee(
var id: Int,
var name: String,
var dept: String,
var joiningDate: String,
var salary: Double
)

Change SQL statement to 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL` for id row. You need to use primitive type

You are using incorrect syntax while defining id row, You have to use Integer as keyword AUTOINCREMENT can be used with INTEGER field only. Change your create table syntax as below and it will work
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,

If you really tried to create the table with this statement:
CREATE TABLE IF NOT EXISTS employees (
id int PRIMARY KEY AUTOINCREMENT NOT NULL,
..........................
);
the result would be this error:
AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY
So, my guess is that the table was not created by that statement, but by a previous statement on which you made changes later. These changes though were not actually reflected to the database, because the table already existed.
What you have to do is either uninstall the app from the device so the db is deleted, or change the version of the db in your SQLiteOpenHelper class so the onUpgrade() method is called which will delete and recreate the table.
So change the CREATE statement to:
CREATE TABLE IF NOT EXISTS employees (
id INTEGER PRIMARY KEY AUTOINCREMENT,
..........................
);
Also, don't use execSQL() to insert rows in the table.
The recommended method is insert():
val cv = ContentValues()
cv.put("name", name)
cv.put("department", dept)
cv.put("joiningdate", joiningDate)
cv.put("salary", salary)
mDatabase.insert("employees", null, cv)

Related

Foreign key isnt created on android studio but tables is created

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.

Unable to query database in Android

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.

How to save Integer to Database(SQLite)

In my program, I have a database and there is a table in my database in the name of the student , In the student table, there is a column named StudentID that should save ten numbers now my problem is The Student ID column can not save the numbers,When I enter numbers less than ten it shows the save message but in logcat have error and when I enter the ten numbers, it will be out from the program.
Sorry for my poor English language.
SQLite Code For Student Table :
create table student(student_id integer(10) primary key not null , class_id int , student_name nvarchar(50) , FOREIGN KEY (class_id) REFERENCES class(class_id))
Save Student Method :
public void SaveStudent(int studentId , int classID , String studentName)
{
ContentValues values = new ContentValues();
values.put("student_id" , studentId);
values.put("class_id" , classID);
values.put("student_name" , studentName);
database.insert("student" , null , values);
Toast.makeText(context, "Save!" , Toast.LENGTH_SHORT).show();
}
Get Student Information :
Button saveStudent_btn = (Button)viewLayout.findViewById(R.id.item_btn_SaveStudent);
saveStudent_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
HashMap<String, Object> obj = (HashMap<String, Object>) adapter.getItem(position);
int classId = (int) obj.get("class_id");
EditText studentName_et = (EditText)viewLayout.findViewById(R.id.item_et_StudentName);
String studentName = studentName_et.getText().toString();
EditText studentId_et = (EditText)viewLayout.findViewById(R.id.item_et_StudentId);
int studentId = Integer.parseInt(studentId_et.getText().toString());
database.OpenDatabase();
database.SaveStudent(studentId , classId , studentName);
database.close();
}
});
Logcat error for when entered 10 numbers:
02-23 19:05:07.850 1896-1896/com.example.user.classmanager E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.classmanager, PID: 1896
java.lang.NumberFormatException: Invalid int: "4318659489"
at java.lang.Integer.invalidInt(Integer.java:138)
at java.lang.Integer.parse(Integer.java:413)
at java.lang.Integer.parseInt(Integer.java:367)
com.example.user.classmanager.SecondTab$1$1$1.onClick(SecondTab.java:94)
at android.view.View.performClick(View.java:5225)
at android.view.View$PerformClick.run(View.java:21195)
at android.os.Handler.handleCallback(Handler.java:739)
logcat error for less then 10 numbers :
02-23 19:42:32.502 10388-10388/com.example.user.classmanager E/SQLiteDatabase: Error inserting
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: student.student_id (code 1555)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:780)
at com.example.user.classmanager.DatabaseHandler.SaveStudent(DatabaseHandler.java:189)
at com.example.user.classmanager.SecondTab$1$1$1.onClick(SecondTab.java:97)
The problem is the length of int, your number overflow.
Use Long instead .
Long studentId = Long.parseLong(studentId_et.getText().toString());
int range in java from -2,147,483,648 To 2,147,483,647 . and your number overflows it .
And for UNIQUE constraint failed you violates the primary key constraints. Make sure the id generated is unique and not null always.
UNIQUE constraint failed this mean you are trying to insert id value which is already exists and that violates the primary key's uniqueness..to a void that make the StudentID auto increment.

Android-SQLiteConstraintException error code 19: constraint failed

I know you have many questions on here about this error, but I cannot understand why all the fields appears to be filled correctly on Logcat, but even so the failure occurs.
Here is the creation of the table:
public void onCreate(SQLiteDatabase db) {
String ddl = "CREATE TABLE Politician (id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE , idpolitician INTEGER NOT NULL, name TEXT NOT NULL, picture TEXT , position TEXT NOT NULL, country TEXT NOT NULL, state TEXT NOT NULL, city TEXT NOT NULL);";
db.execSQL(ddl);
}
Here is where I tried to save.
public void savePolitician(Politician politician) {
ContentValues values = new ContentValues();
values.put("idpolitician", politician.getId());
values.put("name", politician.getName());
values.put("picture", politician.getPictureFilename());
values.put("position", politician.getPosition());
values.put("country", politician.getCountry());
values.put("state", politician.getState());
values.put("city", politician.getCity());
mDatabase.insert("Politician", null, values);
}
And here is the LogCat:
01-08 04:03:31.149 32633-32633/? E/Database﹕ [SQLiteDatabase.java:1428:insert()] Error inserting
state=SP position=governador picture=example idpolitician=1 city=Sao Paulo country=Brasil name=Alckmin
android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:61)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1582)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1426)
at com.politify.dao.DbManegament.savePolitician(DbManegament.java:44)
As you can see all the fields are filled. Anyone can help and tell what i`m doing wrong
try remove AUTOINCREMENT UNIQUE inyour create table script
This is your mistake id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE
When you are defining any column as Primary Key then you do not need to specify it as UNIQUE. Primary Key is by default UNIQUE.

SQLiteException - no such table

Im getting this error when i try to access my View
I've built my database/View using this
CREATE TABLE Boxer(
BoxerId INTEGER PRIMARY KEY AUTOINCREMENT,
Firstname NVARCHAR(50) NOT NULL,
Lastname NVARCHAR(50) NOT NULL
);
CREATE TABLE Match(
MatchId INTEGER PRIMARY KEY AUTOINCREMENT,
BoxerA INTEGER NOT NULL FOREIGN KEY REFERENCES Boxer(BoxerId),
BoxerB INTEGER NOT NULL FOREIGN KEY REFERENCES Boxer(BoxerId),
MatchDate date NOT NULL DEFAULT GETDATE(),
NumberOfRounds INTEGER NOT NULL DEFAULT 12
);
CREATE TABLE Round(
RoundId INTEGER PRIMARY KEY AUTOINCREMENT,
MatchId INTEGER NOT NULL FOREIGN KEY REFERENCES Match(MatchId),
BoxerA INTEGER NOT NULL DEFAULT 0,
BoxerB INTEGER NOT NULL DEFAULT 0,
Position INTEGER NOT NULL
);
/*
Building a view which dislpays matches with boxers names and total scores
*/
CREATE VIEW MatchDetail AS
SELECT Match.MatchId, A.BoxerId AS IdA, B.BoxerId AS IdB, A.Firstname + ' ' + A.Lastname AS NameA, B.Firstname + ' ' + B.Lastname AS NameB,
(SELECT SUM(R.BoxerA) AS Score FROM Round AS R WHERE (R.MatchId = Match.MatchId)) AS ScoreA,
(SELECT SUM(R.BoxerB) AS Score FROM Round AS R WHERE (R.MatchId = Match.MatchId)) AS ScoreB,
Match.MatchDate, Match.NumberOfRounds
FROM Boxer AS A INNER JOIN Match ON A.BoxerId = Match.BoxerA INNER JOIN Boxer AS B ON Match.BoxerB = B.BoxerId
I've pretty much built my app so far using the notepad example so I then call my DbHelper
Cursor MatchesCursor = mDbHelper.fetchAllMatchDetails();
This then calls the query
public Cursor fetchAllMatchDetails(){
return mDb.query(VIEW_MATCHDETAIL, new String[] {
"MatchId"
}, null, null, null, null, null);
}
VIEW_MATCHDETAIL is defined as a string = "MatchDetail"
and it's here where it crashes saying
no such table MatchDetail: while compiling SELECT MatchId FROM MatchDetail
anyone had this problem before?
You have some beautiful SQL there. Unfortunately only the first line of sql will be executed in SQLiteDatabase.execSQL. The rest will be ignored silently (convenient eh?). Split up the statements manually like this:
https://github.com/browep/fpt/blob/master/src/com/github/browep/nosql/NoSqlSqliteOpener.java
or if you like to keep your sql in a separate file, try this:
String sqlText = getSqlText();
for(String sqlStmt : sqlText.split(";"))
myDb.execSQL(slqStmt + ";");
What stands out to me is the use of datatypes like NVARCHAR(50). SQLite only has a very simple set of datatypes. I'm surprised it doesn't throw an exception when you install the app. Try using simply TEXT instead.
If you cannot access a database that you know you have initialized, try passing the Context from the Activity that created the table to the class trying to query the table. Use that Context as part of your connection initialization.

Categories

Resources