In Android SQLite, I am trying to get some details of customers when I am online, store it in SQLite database, and display them when I am offline.
Unfortunately when doing it so, that the order of the columns get unfortunately messed up.
I have the following table, TABLE_AGEING_VALUES_ALL:
Loan_No text primary key,
agreement_date date,
branch_name text,
loan_status text,
address1 text,
address2 text,
status_type integer,
user_id integer
The customer details are displayed like this when I am online:
Example 1:
Loan Number: CDAGRTW1412090016
Agreement Date: 12/9/2014 12:00:00 AM
Branch Name:
Loan Status: Expired
Address 1: 9/43, MOTI BAG NAGAL FATHORI YAMUNA BRIDGE
Address 2:
Unfortunately, when I am offline, the order of the fields get messed up like this.
Example 1:
Loan Number: CDAGRTW1412090016
Agreement Date:
Branch Name: 9/43, MOTI BAG NAGAL FATHORI YAMUNA BRIDGE
Loan Status:
Address 1: Expired
Address 2: 12/9/2014 12:00:00 AM
I would like to know why that it should ever happen so, at all.
Here is my update or insert function call in main activity fragment Java file, that depending upon if whether, within any given case that row already exists or not:
onResponse() function call:
if (db.selectAgeingvalues(Loan_No, status_type, user_id) == 0) {
db.insertAgeingvalues(Loan_No, agreement_date, branch_name, loan_status, address1, address2, status_type, user_id);
} else {
db.updateAgeingvalues(Loan_No, agreement_date, branch_name, loan_status, address1, address2, status_type, user_id);
}
Here is my select function call to retrieve details of customers from stored Android SQLite database table when I am offline:
onFailure() function call:
sqliteDB db = new sqliteDB(getActivity());
List<String> AgeingvaluesList[] = db.selectAgeingvalues("-1", user_id);
for(int i = 0; i < AgeingvaluesList[0].size(); i++)
{
Loan_No = AgeingvaluesList[0].get(i);
agreement_date = AgeingvaluesList[1].get(i);
branch_name = AgeingvaluesList[2].get(i);
loan_status = AgeingvaluesList[3].get(i);
address1 = AgeingvaluesList[4].get(i);
address2 = AgeingvaluesList[5].get(i);
status_type = AgeingvaluesList[6].get(i);
}
Here are my SELECT, INSERT, UPDATE, onCreate() and onUpgrade() function calls inside of my own declared sqliteDB.java Java file, as follows, as like, such as, those like:
onCreate(SQLiteDatabase sqLiteDatabase) function call
in order to be able to be creating a table TABLE_AGEING_VALUES_ALL into the stored Android SQLite database table if it already does not exist or dropping it and recreating it if it already exists, based upon following assigned values of variable, sqLiteDatabase:
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// TODO Auto-generated method stub
sqLiteDatabase.execSQL(
"create table " + TABLE_AGEING_VALUES_ALL +
"("
+ "Loan_No text not null unique primary key,"
+ "branch_name text,"
+ "address1 text not null,"
+ "address2 text,"
+ "loan_status text not null,"
+ "agreement_date text not null,"
+ "status_type number not null,"
+ "user_id text not null"
+ ")"
);
}
onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) function call
in order to be able to be upgrading a table TABLE_AGEING_VALUES_ALL into the stored Android SQLite database table if it already exists or not during upgradation of mobile application to a newer version or during uninstallation and reinstallation of mobile application to a newer version, based upon following assigned values of variables, sqLiteDatabase, i and i1:
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
// TODO Auto-generated method stub
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_AGEING_VALUES_ALL);
onCreate(sqLiteDatabase);
}
insertAgeingvalues(String Loan_No, String agreement_date, String branch_name, String loan_status, String address1, String address2, String status_type, String user_id) function call
in order to be able to be inserting a row into the stored Android SQLite database table if it already does not exist, based upon following assigned values of variables, Loan_No, agreement_date, branch_name, loan_status, address1, address2, status_type and user_id:
public boolean insertAgeingvalues(String Loan_No, String agreement_date, String branch_name, String loan_status, String address1, String address2, String status_type, String user_id)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("Loan_No", Loan_No);
contentValues.put("agreement_date", agreement_date);
contentValues.put("branch_name", branch_name);
contentValues.put("loan_status", loan_status);
contentValues.put("address1", address1);
contentValues.put("address2", address2);
contentValues.put("status_type", status_type);
contentValues.put("user_id", user_id);
db.insert(TABLE_AGEING_VALUES_ALL, null, contentValues);
return true;
}
updateAgeingvalues(String Loan_No, String agreement_date, String branch_name, String loan_status, String address1, String address2, String status_type, String user_id) function call:
in order to be able to be updating a row into the stored Android SQLite database table if it already exists, based upon following assigned values of variables, Loan_No, agreement_date, branch_name, loan_status, address1, address2, status_type and user_id:
public int updateAgeingvalues(String Loan_No, String agreement_date, String branch_name, String loan_status, String address1, String address2, String status_type, String user_id)
{
SQLiteDatabase db = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("Loan_No", Loan_No);
contentValues.put("agreement_date", agreement_date);
contentValues.put("branch_name", branch_name);
contentValues.put("loan_status", loan_status);
contentValues.put("address1", address1);
contentValues.put("address2", address2);
contentValues.put("status_type", status_type);
contentValues.put("user_id", user_id);
// updating row
return db.update(TABLE_AGEING_VALUES_ALL, contentValues, "Loan_No = ? AND user_id = ?",
new String[] {Loan_No, user_id});
}
selectAgeingvalues(String Loan_No, String status_type, String user_id) function call
Android SQLite database table:
public int selectAgeingvalues(String Loan_No, String status_type, String user_id)
{
int count = 0;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
cursor = db.rawQuery("SELECT EXISTS(SELECT Loan_No FROM " + TABLE_AGEING_VALUES_ALL + " WHERE user_id = \"" + user_id + "\" AND Loan_No = \"" + Loan_No + "\" AND status_type = " + status_type + ")", null);
if (cursor.moveToFirst()) {
do {
count = Integer.parseInt(cursor.getString(0));
} while (cursor.moveToNext());
}
return count;
}
selectAgeingvalues(String status_type, String user_id) function call
in order to be able to be retrieving a row from the stored Android SQLite database table if it already exists or not, based upon following assigned values of variables, status_type and user_id:
public List<String>[] selectAgeingvalues(String status_type, String user_id)
{
String Loan_No;
String agreement_date;
String branch_name;
String loan_status;
String address1;
String address2;
List AgeingvaluesList[] = new List[7];
for(int i = 0; i <= 6; i++) {
AgeingvaluesList[i] = new ArrayList<String>();
}
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
cursor = db.rawQuery("SELECT * FROM "+TABLE_AGEING_VALUES_ALL+" WHERE user_id = \""+user_id+"\" AND status_type = "+status_type, null);
if (cursor.moveToFirst()) {
do {
Loan_No = cursor.getString(0);
AgeingvaluesList[0].add(Loan_No);
agreement_date = cursor.getString(1);
AgeingvaluesList[1].add(agreement_date);
branch_name = cursor.getString(2);
AgeingvaluesList[2].add(branch_name);
loan_status = cursor.getString(3);
AgeingvaluesList[3].add(loan_status);
address1 = cursor.getString(4);
AgeingvaluesList[4].add(address1);
address2 = cursor.getString(5);
AgeingvaluesList[5].add(address2);
status_type = cursor.getString(6);
AgeingvaluesList[6].add(status_type);
} while (cursor.moveToNext());
}
return AgeingvaluesList;
}
What am I doing wrongly enough?
Instead of cursor.getString(1); change it to cursor.getString(cursor.getColumnIndex("Loan_No ")); and do this for all the respective fields.
Always use column name instead of position, because column position can change.
of course column name can change as well but let say if you add a new column and it position between column 1 and column 2. You need to change your code if you use number. But if you use name, you will be fine.
(D.'s original answer, keeping it all for reference purposes only).
I think your problem is in the
for(int i = 0; i < AgeingvaluesList[0].size(); i++)
With this AgeingvaluesList[0].size(); you are only getting the size of the first element and that's also the size of the first element!
Change it to AgeingvaluesList().size();
also please would you mind instead of cursor.getString(1); change it to cursor.getString(cursor.getColumnIndex("Loan_No ")); and do this for all the respective fields
Related
I have a recyclerview cardholder that inflates using the values of 'NAME' from the table 'ORDERTABLE'. The cardholder also have an EditText which displays the values of column 'QUANTITY' in my SQLite database.
I also have a button to update the database for every changes in EditText.
I have this table ORDERTABLE
id NAME QUANTITY
1 Order1 1
2 Order2 1
3 Order3 1
4 Order4 1
Being more specific, how can i update the QUANTITY of Order2 on onButtonPressed with the new values of my EditText.
EDIT...
I have tried this code but nothing happened
Button to update values
public void addButtonClick(TextView tv_cardrowName_atc, TextView tv_currentPrice_atc, EditText et_quantity_atc, int position) {
int thisQuantity = Integer.parseInt(et_quantity_atc.getText().toString());
thisQuantity++;
String orderName = tv_cardrowName_atc.getText().toString();
String oldQuantity = et_quantity_atc.getText().toString();
String newQuantity = String.valueOf(thisQuantity);
sqliteCBLCAdapter.selectUpdateItem(orderName, oldQuantity, newQuantity);
et_quantity_atc.setText(String.valueOf(thisQuantity));
}
Update Method
public String selectUpdateItem(String orderName, String oldQuantity, String newQuantity) {
SQLiteDatabase sqLiteDatabase = sqLiteCBLC.getWritableDatabase();
String[] columns = {SQLiteCBLC.COL_ORDNAME, SQLiteCBLC.COL_QUANTITY};
Cursor cursor = sqLiteDatabase.query(SQLiteCBLC.TABLE_NAME, columns, SQLiteCBLC.COL_ORDNAME + " = '" + orderName + "'", null, null, null, null);
StringBuffer stringBuffer = new StringBuffer();
while (cursor.moveToNext()) {
int index1 = cursor.getColumnIndex(SQLiteCBLC.COL_ORDNAME);
int index2 = cursor.getColumnIndex(SQLiteCBLC.COL_QUANTITY);
String order = cursor.getString(index1);
String quantity = cursor.getString(index2);
ContentValues contentValues = new ContentValues();
contentValues.put(SQLiteCBLC.COL_QUANTITY, newQuantity);
String[] whereArgs = {quantity};
sqLiteDatabase.update(SQLiteCBLC.TABLE_NAME, contentValues, SQLiteCBLC.COL_QUANTITY + " =? ", whereArgs);
stringBuffer.append(order);
}
return stringBuffer.toString();
}
The easiest way for you to achieve this would be to use a SQL update query as follows:
From the SQLite Web Site:
The SQLite UPDATE Query is used to modify the existing records in a table. You can use a WHERE clause with UPDATE query to update selected rows, otherwise all the rows would be updated.
The syntax for the update query is as follows:
UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];
So in your case your sql update query would look some thing like this:
UPDATE ORDERTABLE SET QUANTITY = (INSERT VALUE OF YOUR EDIT TEXT) WHERE NAME = 'Order2'
You can then execute your query by using the execSQL() method of your SQLiteDatabase object that you have and passing in the sql query above as the string parameter.
You can try like this below code, In your case you while updating you are updating based on quantity, multiple order will have the same quantity. just check the order name and update it.
public void selectUpdateItem(String orderName, String oldQuantity, String newQuantity) {
if (TextUtils.isEmpty(order)) {
return;
}
ContentValues contentValues = new ContentValues();
final String whereClause = SQLiteCBLC.COL_ORDNAME + " =?";
final String[] whereArgs = {
orderName
};
// if you want to update with respect of quantity too. try this where and whereArgs below
//final String whereClause = SQLiteCBLC.COL_ORDNAME + " =? AND " + SQLiteCBLC.COL_QUANTITY + " =?";
//final String[] whereArgs = {
//orderName, String.valueOf(oldQuantity)
//};
contentValues.put(SQLiteCBLC.COL_QUANTITY, newQuantity);
SQLiteDatabase sqLiteDatabase = sqLiteCBLC.getWritableDatabase();
sqLiteDatabase.update(SQLiteCBLC.TABLE_NAME, contentValues,
whereClause, whereArgs);
}
This question already has answers here:
When does SQLiteOpenHelper onCreate() / onUpgrade() run?
(15 answers)
Closed 6 years ago.
I am trying to add a TIMESTAMP Column to my SQLite database. The column is to be used to capture timestamp data using "System.currentTimeMillis();". App is crashing and the error is from the cursor code shown below in the line with ** **. The error reads "Unable to start activity ComponentInfo{...ListActivity}: java.lang.IllegalStateException: Couldn't read row 0, col 6 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it."
Initially I set up the variable as a String in the model file. Then I tried a long and neither worked. What am I missing here?
UserData file:
...
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
DatabaseHelper.java file:
...
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE IF NOT EXISTS " + DBContract.DBEntry.TABLE_NAME +
"(" + DBContract.DBEntry.COLUMN_NAME_ID +
" INTEGER PRIMARY KEY AUTOINCREMENT,"
+ DBContract.DBEntry.COLUMN_NAME_TODO +
" TEXT,"
+ DBContract.DBEntry.COLUMN_NAME_NOTE1 +
" TEXT,"
+ DBContract.DBEntry.COLUMN_NAME_NOTE2 +
" TEXT,"
+ DBContract.DBEntry.COLUMN_NAME_DUEDATE +
" TEXT,"
+ DBContract.DBEntry.COLUMN_NAME_DUETIME +
" TEXT,"
+ DBContract.DBEntry.COLUMN_NAME_TIMESTAMP +
" TEXT" + ")";
...
public void insertIntoDB(String todo, String note1, String note2, String duedate, String duetime, long timestamp) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DBContract.DBEntry.COLUMN_NAME_TODO, todo);
values.put(DBContract.DBEntry.COLUMN_NAME_NOTE1, note1);
values.put(DBContract.DBEntry.COLUMN_NAME_NOTE2, note2);
values.put(DBContract.DBEntry.COLUMN_NAME_DUEDATE, duedate);
values.put(DBContract.DBEntry.COLUMN_NAME_DUETIME, duetime);
values.put(DBContract.DBEntry.COLUMN_NAME_TIMESTAMP, timestamp);
db.insert(DBContract.DBEntry.TABLE_NAME, null, values);
db.close();
}
...
Cursor cursor = db.rawQuery(query,null);
try {
if (cursor.moveToFirst()) {
do {
UserData userData = new UserData();
userData.setTodo(cursor.getString(1));
userData.setNote1(cursor.getString(2));
userData.setNote2(cursor.getString(3));
userData.setDuedate(cursor.getString(4));
userData.setDuetime(cursor.getString(5));
**userData.setTimestamp(cursor.getLong(6));**
modelList.add(0, userData);
} while (cursor.moveToNext());
...
ListAdapter.java file:
...
public void onBindViewHolder(final ListViewHolder holder, final int position) {
...
holder.cardBlankText5.setText((int) dbList.get(position).getTimestamp());
Activity.java file:
...
public void onClickSave(View v) {
...
long timestamp=System.currentTimeMillis();
helper = new DatabaseHelper(Activity.this);
helper.insertIntoDB(todo,note1,note2,duedate,duetime,timestamp);
startActivity(new Intent(Activity.this,ListActivity.class));
}
Having DBContract.DBEntry.COLUMN_NAME_TIMESTAMP as a DATETIME type should work. I usually have utility method that takes the cursor and column name and returns a Date object:
public static Date getDateColumn(Cursor c, String column) {
Date d = null;
Long time = c.getLong(c.getColumnIndexOrThrow(column));
if (time != null && time != 0) {
d = new Date();
d.setTime(time);
}
return d;
}
The second thing to check is whether or not that field is being asked for in your query. Sharing the value of query could shed some light, but usually you get things like this when the column you are asking for isn't in the projection.
e.g. select columnA, columnB from mytable; and then you try to get something from columnC which isn't in the results.
Don't try to get Long from column declared as TEXT. Declare it as INTEGER.
Or use getString() and convert value to Long.
I have the following code in a bigger project:
final class DBlifetimeStatisticsHandler{ //implements DBvalueHandler<Cyclist, Double>{
private final String TAG = getClass().getName();
private static final boolean debug = true;
private final DBminMaxAvgHandler dbMinMaxAvgHandler = new DBminMaxAvgHandler();
// table name
private static final String TABLE_LIFETIME_STATISTICS = "lifetime_statistics";
// column names
private static final String KEY_LIFETIME_STATISTICS_ID = "lifetime_statistics_id";
private static final String KEY_MIN_MAX_AVG = "min_max_avg";
// table create statement
private static final String CREATE_TABLE = "CREATE TABLE "
+ TABLE_LIFETIME_STATISTICS + "("
+ KEY_LIFETIME_STATISTICS_ID + " LONG PRIMARY KEY NOT NULL,"
+ KEY_MIN_MAX_AVG + " LONG"
+ ")";
public void onCreateTable(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
}
public void onUpgrade(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LIFETIME_STATISTICS);
onCreateTable(db);
}
public long addValue(SQLiteDatabase db, Statistics Statistics ) {
ContentValues values = new ContentValues();
long ID = getLatestID(db)+1;
values.put(KEY_STATISTICS_ID, ID);
... //not important to the question
}
private long getLatestID(SQLiteDatabase db){
String selectQuery = "SELECT MAX(" + KEY_STATISTICS_ID +") FROM " + TABLE_STATISTICS;
Cursor c = db.rawQuery(selectQuery, null);
c.moveToFirst();
int id = 0;
Log.e("count", String.valueOf(c.getCount()));
if (c.moveToFirst()){
...
}
return id;
}
}
After I updated the table it is created again. So when I try to add a new value I had problems cause it always jumped into the if clause because c.moveToFirst() always returned true.
So I tried to tried to check if c.getCount() would return true but sadly it does always return 1. So the question is: Why would it return 1 on an empty table? (I do use Questoid SQLite Browser and the table is really empty)
You use aggregate function MAX, so read documentation:
There are two types of simple SELECT statement - aggregate and non-aggregate queries. A simple SELECT statement is an aggregate query if it contains either a GROUP BY clause or one or more aggregate functions in the result-set.
An aggregate query without a GROUP BY clause always returns exactly one row of data, even if there are zero rows of input data.
It might be some kind of a buggy behavior when using MAX. Check this link too Android database (SQLite) returns a non-empty cursor from an empty table
this is my solution
public Boolean isNotEmpty(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_STATISTICS, null);
while (cursor.moveToNext() ) {
return true;
}
return false;
}
You are getting a result with one row in your Cursor because that is what you requested.
The result is a single column called MAX with a value that will be the max id of all the rows in your table. In your case of an empty table, this value is null.
I am using group by to resolve this. Please check my example :
SELECT COUNT(*) FROM " + TABLE_NAME + " WHERE isSynced=0 group by isSynced
I resolve this probme this way:
SELECT COUNT(*) AS numero, MAX(tagua_lagps) as tmp_max_lagps, MAX(tagua_logps) as tmp_max_logps, MIN(tagua_lagps) as tmp_min_lagps, MIN(tagua_logps) as tmp_min_logps FROM TAB_AGUA
On empty table, c.getCount(); gives 1 but values are NULL. But numero (c.getString(c.getColumnIndex("numero")) has a value of 0.
So rather than checking c.getCount() you must check the result of count(*).
This works to Insert a Row
public long insertRows(Double lat, Double log, String mdate,
String mycomment, String name) {
ContentValues value=new ContentValues();
value.put(COLUMN2,lat);
//System.out.println(COLUMN2+lat);
value.put(COLUMN3, log);
//System.out.println(COLUMN3+log);
value.put(COLUMN4, mdate);
//System.out.println(COLUMN4+mdate);
value.put(COLUMN5, mycomment);
//String mycomment = null;
//System.out.println(COLUMN5+mycomment);
value.put(COLUMN6, name);
return db.insert(TABLENAME,null,value);}
But I am unable to Delete a row programmatically.
I can provide more code or info if needed any help is greatly appreciated
this is what Im useing so far seems intemitant though
and Im still haveing issues updateing the listactivity
public boolean deleteEntry(long Id) {Id = GpsListactivity.rowid;
System.out.println("GPSDATABASE "+ TABLENAME + KEY_ROWID + "=" +Id);
return db.delete(TABLENAME,KEY_ROWID + "="+Id,null) > 0;}
// this is the update method
public boolean update(long Id, Double lat, Double log,
String mdate,String mycomment, String name) {
ContentValues updateValues = createContentValues(
lat,log,mdate,mycomment,name);
return db.update(TABLENAME, updateValues,"locationId=?" +Id,null) > 0;
You can use the method delete(String table, String whereClause, String[] whereArgs). For example:
String whereClause = "COLUMN4 = 'value'";
db.delete(TABLENAME, whereClause, null);
To delete a specific row, you will have to know information about that row which makes it unique (for example the row's primary key or a combination of data in its columns).
You can also reference the SQLiteDatabase documentation for more information.
I am trying to insert data in my sqlit database but I got android SQLiteConstraintException: error code 19: constraint failed exception. I saw there are tons of question in this topic, I've read and tried a bunch of them, but the exception still , i wonder if this exception caused by the auto increment food_id value , since the insert statement return -1 , and i wonder that why this exception occur since the first insert id done correctly but all the later inserting are failed , why this error occur ,and how i can solve it? please help me..
the create statements in the DBAdapter class
private static final String Meal_TABLE_CREATE= "create table IF NOT EXISTS Meal (Date text not null , "+
"Time text not null,MealType text not null,"+ " primary key(Date,Time ,MealType) );" ;
private static final String FOOD_TABLE_CREATE= "create table IF NOT EXISTS Food (_id INTEGER primary key AUTOINCREMENT , "+
"Food_Name text not null,Calories integer not null,"+ "VB12 integer not null,Cholesterol integer not null,"+
"Protein integer not null,Iron integer not null,Sodium integer not null,Fat_Mono integer not null,Fat_Sat integer not null,carbohydrate integer not null);" ;
private static final String MealFOOD_TABLE_CREATE= "create table IF NOT EXISTS MealFood (Date text not null , "+
"Time text not null,MealType text not null,"+"Food_ID integer not null , primary key(Date,Time ,MealType,Food_ID) );" ;
inserting methods
// insert meal to the meal table
public long SaveMeal(String date , String time , String mealType)
{
ContentValues content = new ContentValues();
content.put(KEY_MDATE,date);
content.put(KEY_MTIME,time);
content.put(KEY_MEALTYPE,mealType);
return db.insert(MEAL_TABLE_NAME, null, content);
}
// insert Food to the Food table
public long SaveFood(String name,int calories,int Vit_B12,int cholesterol,int protein ,int iron ,int sodium,int Fat_Mono,int Fat_Sat,int carbohydrate)
{
ContentValues content = new ContentValues();
content.put(KEY_FOODNAME,name);
content.put(KEY_CALORIES,calories);
content.put(KEY_VB12,Vit_B12);
content.put(KEY_CHOLESTEROL,cholesterol);
content.put(KEY_PROTEIN,protein);
content.put(KEY_IRON,iron);
content.put(KEY_SODIUM,sodium);
content.put(KEY_FAT_MONO,Fat_Mono);
content.put(KEY_FAT_Sat,Fat_Sat);
content.put(KEY_CARBOHYDRATE,carbohydrate);
return db.insert(FOOD_TABLE_NAME, null, content);
}
// get food id by its name
public int getFoodIDByName(String name) throws SQLException
{ int id;
Cursor cursor = null;
try{
cursor=db.query(true,FOOD_TABLE_NAME, new String[]{KEY_FOODID}, KEY_FOODNAME+ " = '" + name + "'", null, null, null, null,null);
if (cursor != null) {
cursor.moveToFirst();
}
id=0;
while (cursor.moveToNext())
id=cursor.getInt(cursor.getColumnIndex(KEY_FOODID));
}
finally{
cursor.close();
cursor.deactivate();
}
return id;
}
// insert mealFood to mealFood table
public long SaveMealFood(String date , String time , String mealType, int Food_id)
{
ContentValues content = new ContentValues();
content.put(KEY_MFDATE,date);
content.put(KEY_MFTIME,time);
content.put(KEY_MFMEALTYPE,mealType);
content.put(KEY_MFFOODID,Food_id);
return db.insert(MEALFOOD_TABLE_NAME, null, content);
}
java code
DBAdapter dbAdapter=new DBAdapter(SaveMeal.this);
dbAdapter.open();
Food n;
String m;
int FoodIDByName;
for(int i = 0; i <MealActivity.array.size(); i++){
m=MealActivity.array.get(i).toString();
Log.e("tag", m);//selected food name
for (int j = 0; j < MealActivity.tempList.size(); j++){
n=MealActivity.tempList.get(j);
if(n.getFOOD_NAME().equals(m)){
//save food
long food_id = dbAdapter.SaveFood(n.getFOOD_NAME(),n.getCALORIES(),n.getFOOD_VITAMIN_B12(),n.getCHOLESTEROL(),n.getFOOD_PROTEIN(),n.getFOOD_IRON(),n.getFOOD_SODIUM(),
n.getFOOD_MONO_UNSATURATED_FAT(),n.getFOOD_SATURATED_FAT(),n.getFOOD_TOTAL_CARBOHYDRATE());
Log.e("tag", food_id+" food inserting done");
//save meal
long meal_id= dbAdapter.SaveMeal( meal_date,meal_time,Meal.MEAL_TYPE);
Log.e("tag",meal_id+" meal inserting done");
//save meal_food
FoodIDByName=dbAdapter.getFoodIDByName(n.FOOD_NAME);
Log.e("tag",FoodIDByName+" food_id");
long meal_food_id=dbAdapter.SaveMealFood(meal_date,meal_time,Meal.MEAL_TYPE,FoodIDByName);
Log.e("tag",meal_food_id+" meal_food inserting done");
dbAdapter.close();
this result of this line Log.e("tag", food_id+" food inserting done"); in my log is -1
mylog
Database(657):at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
Database(657):at android.database.sqlite.SQLiteStatement.execute (SQLiteStatement.java:55)
Database(657):at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1410)
-1 food inserting done
18 meal inserting done
0 food_id
13 meal_food inserting done
Try to remove all (Not NULL) constraints, and save the empty food.
If it is saved properly, try to add the constraint (NOT NULL) one by one.
I think one of the values is passed as NULL.
That error.means you are.violating a constraint (obviously). Most likely leave a "not null" column null.
You could also have violated your primary key by trying to save the same combination more than once.