I got error in following code. I am trying to save my traveled distance in SQLite Database but getting error in SQLite Database. I don't know how to manage the array length. I am getting an error called
java.lang.ArrayIndexOutOfBoundsException: length=3; index=4.
public class ActivityLocationDaoImpl extends Dao implements ActivityLocationDao {
private static final String TABLE_NAME = "activity_location";
private static final String COLUMN_ID = "id";
private static final String COLUMN_LATITUDE = "latitude";
private static final String COLUMN_LONGITUDE = "longitude";
private static final String COLUMN_ACTIVITY = "activity";
private static final String COLUMN_DATE = "date";
private static final String[] COLUMN_ARRAY = new String[]{COLUMN_ID, COLUMN_LATITUDE, COLUMN_LONGITUDE, COLUMN_ACTIVITY, COLUMN_DATE};
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (\n" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,\n" +
COLUMN_LATITUDE + " INTEGER NOT NULL,\n" +
COLUMN_LONGITUDE + " INTEGER NOT NULL,\n" +
COLUMN_ACTIVITY + " INTEGER NOT NULL,\n" +
COLUMN_DATE + " INTEGER NOT NULL\n" + ")";
public ActivityLocationDaoImpl(SQLiteDatabase database) {
super(database);
}
#Override
public boolean insert(ActivityLocation activityLocation) {
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_LATITUDE, activityLocation.getLocation().getLatitude());
contentValues.put(COLUMN_LONGITUDE, activityLocation.getLocation().getLongitude());
contentValues.put(COLUMN_ACTIVITY, activityLocation.getActivityType().getIndex());
contentValues.put(COLUMN_DATE, activityLocation.getDate().getTime());
return getDatabase().insert(TABLE_NAME, null, contentValues) != -1;
}
#Override
public List<ActivityLocation> listAll(Date currentDay) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(currentDay);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
currentDay = calendar.getTime();
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 1);
Date nextDay = calendar.getTime();
Cursor cursor = getDatabase().query(TABLE_NAME, COLUMN_ARRAY, COLUMN_DATE + " > ? AND " + COLUMN_DATE + " < ?",
new String[]{String.valueOf(currentDay.getTime()), String.valueOf(nextDay.getTime())},
null, null, COLUMN_DATE + " ASC", null);
List<ActivityLocation> activityLocationList = new ArrayList<>();
while (cursor.moveToNext()) {
activityLocationList.add(convertCursorToEntity(cursor));
}
return activityLocationList;
}
#Override
public List<ActivityLocation> listAll(Date startDate, Date finalDate) {
Cursor cursor = getDatabase().query(TABLE_NAME, COLUMN_ARRAY, COLUMN_DATE + " > ? AND " + COLUMN_DATE + " < ?",
new String[]{String.valueOf(startDate.getTime()), String.valueOf(finalDate.getTime())},
null, null, COLUMN_DATE + " ASC", null);
List<ActivityLocation> activityLocationList = new ArrayList<>();
while (cursor.moveToNext()) {
activityLocationList.add(convertCursorToEntity(cursor));
}
return activityLocationList;
}
public ActivityLocation convertCursorToEntity(Cursor cursor) {
ActivityLocation activityLocation = new ActivityLocation();
Location location = new Location();
activityLocation.setId(cursor.getInt(0));
location.setLatitude(cursor.getDouble(1));
location.setLongitude(cursor.getDouble(2));
activityLocation.setLocation(location);
activityLocation.setActivityType(ActivityType.values()[cursor.getInt(3)]);
activityLocation.setDate(new Date(cursor.getLong(4)));
return activityLocation;
}
Getting Error on this line :
activityLocation.setActivityType(ActivityType.values()[cursor.getInt(3)]);
Thanks in advance.
Most probably, the cursor only contains 3 resulting columns. Therefore you can only access 0, 1 and 2.
Shravan, you can't fetch 4th index value from the array when there are only 3 values.
You can access the index values of 0,1,2 only.
Use breakpoint on the crashing line and you will get a clear picture.
Well, you cant access 4th element of an array having just 3 elements. Mostly people confuse this having a little background in C/C++.
This is the difference in C/C++ and JAVA.
Suppose you have something like this:
int arr[] = {1,2,3};
Now, if you do arr[3] in C/C++, it will return some garbage value, whatever is present at the that particular address, but in JAVA , ArrayIndexOutOfBoundsException is thrown.
Related
This question already has answers here:
When does SQLiteOpenHelper onCreate() / onUpgrade() run?
(15 answers)
Closed 7 years ago.
I'm trying to update a particular row of a database, and I have the following code
public String CREATE_QUERY = "CREATE TABLE " + TableData.TableInfo.TABLE_NAME +
"(" + TableData.TableInfo.USER_NAME + " TEXT, " + TableData.TableInfo.USER_PIN +
" TEXT, " + TableData.TableInfo.PARTNER_FIRST + " Text, " + TableData.TableInfo.PARTNER_SECOND +
" TEXT, " + TableData.TableInfo.DATE + " TEXT, " + TableData.TableInfo.SIGNATURE_IMAGE + " BLOB, " +
TableData.TableInfo.PARTNER_SIGNATURE + " BLOB);";
And I am getting an error from
ContentValues cv = new ContentValues();
DatabaseOperations DOP = new DatabaseOperations(ctx);
Cursor CR = DOP.getInformation(DOP);
CR.moveToLast();
SQLiteDatabase SQ = DOP.getWritableDatabase();
ContentValues args = new ContentValues();
args.put(TableData.TableInfo.USER_NAME, CR.getString(0));
args.put(TableData.TableInfo.PARTNER_FIRST, partner_name);
SQ.update(TableData.TableInfo.TABLE_NAME, args, "ROWID=?" + id, null);
This is the error:
Caused by: android.database.sqlite.SQLiteException: no such column: partner_first (code 1): , while compiling: UPDATE reg_info SET user_name=?,partner_first=? WHERE ROWID=?54
Here is my table info
public static abstract class TableInfo implements BaseColumns {
public static final String USER_NAME = "user_name";
public static final String USER_PIN = "user_pin";
public static final String PARTNER_FIRST = "partner_first";
public static final String PARTNER_SECOND = "partner_second";
public static final String DATE = "date";
//public static final String LOC = "location";
public static final String SIGNATURE_IMAGE = "signature_image";
public static final String PARTNER_SIGNATURE = "partner_signature";
public static final String DATABASE_NAME = "user_info";
public static final String TABLE_NAME = "reg_info";
}
What am I doing wrong?
Uninstall and rename the database.. This happens frequently when you
change your table name or any change in database.
The problem is in your UPDATE statement - you have a concatenated string and are not passing the "WHERE" arg correctly on this line:
SQ.update(TableData.TableInfo.TABLE_NAME, args, "ROWID=?" + id, null);
simply do this:
SQ.update(TableData.TableInfo.TABLE_NAME, args, "ROWID=" + id, null);
the error is misleading because the SQL statement is wrong altogether.
Why is that when i have more than 3 columns the app crashes? I tried debugging it by commenting out one column and it runs perfectly. After debugging it some more I found out that the problem might be on the 'populateListview' because I was able to run the app but now it won't display anything. Why do you think I couldn't run it with more than 3 columns?
Here's my dbAdapter:
// Field Names:
public static final String KEY_ROWID = "_id";
public static final String KEY_INGREDIENTNAME = "ingredientname";
public static final String KEY_IMAGE = "image";
public static final String KEY_DETAILS = "details";
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_INGREDIENTNAME, KEY_IMAGE, KEY_DETAILS};
// Column Numbers for each Field Name:
public static final int COL_ROWID = 0;
public static final int COL_INGREDIENTNAME = 1;
public static final int COL_IMAGE = 2;
public static final int COL_DETAILS = 3;
//SQL statement to create database
private static final String DATABASE_CREATE_SQL =
"CREATE TABLE " + DATABASE_TABLE
+ " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_INGREDIENTNAME + " TEXT NOT NULL, "
+ KEY_IMAGE + " TEXT"
+ KEY_DETAILS + " TEXT"
+ ");";
// Add a new set of values to be inserted into the database.
public long insertRow(String ingredientname, String image, String detailsValue) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_INGREDIENTNAME, ingredientname);
initialValues.put(KEY_IMAGE, image);
initialValues.put(KEY_DETAILS, detailsValue);
// Insert the data into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
// Return all data in the database.
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
Here's my populateListView Code:
private void populateListView() {
Cursor cursor = myDb.getAllRows();
String[] fromFieldNames = new String[] { //DBAdapter.KEY_ROWID,
DBAdapter.KEY_INGREDIENTNAME };
int[] toViewIDs = new int[] { //R.id.textViewItemNumber,
R.id.textViewItemTask };
SimpleCursorAdapter myCursorAdapter;
myCursorAdapter = new SimpleCursorAdapter(getBaseContext(),
R.layout.item_layout, cursor, fromFieldNames, toViewIDs, 0);
ListView myList = (ListView) findViewById(R.id.listViewTask);
myList.setAdapter(myCursorAdapter);
}
You miss a comma, here:
private static final String DATABASE_CREATE_SQL =
"CREATE TABLE " + DATABASE_TABLE
+ " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_INGREDIENTNAME + " TEXT NOT NULL, "
+ KEY_IMAGE + " TEXT"
+ KEY_DETAILS + " TEXT"
+ ");";
It should be
private static final String DATABASE_CREATE_SQL =
"CREATE TABLE " + DATABASE_TABLE
+ " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_INGREDIENTNAME + " TEXT NOT NULL, "
+ KEY_IMAGE + " TEXT,"
+ KEY_DETAILS + " TEXT"
+ ");";
my problem is with very specific query. My SQLite datbase is only 1 table with 11 entries. It creates just fine, but upon execution of this piece of code it crashes. When I change the query to simply:
SELECT * FROM Items
Then it works fine, but I need more narrow results, therefore I modify with the "WHERE" clause. But then it crashes and the application stops. If I comment out the Cursor... it runs fine.
public int findPictureNumber(String itemtitle) {
String query = "SELECT nr_of_pics FROM Items WHERE ItemTitle = \"" + itemtitle + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
...
}
Where is the error? I can't seem to find it even after narrowing it down to those lines of code.
EDIT:
This is a method for adding an item to a database.
public void newItemFuro () {
MyDBHandler dbHandler = new MyDBHandler(this, null, null, 1);
String title = "Furo";
String author = "Fernando Brizio";//í
String category = "Decoracao";//çã
int date = 2012;
String type = "Taca";//ç
String country = "Portugal";
String colour = "Castanho/Cortica";//ç
String material = "Castanho/Cortica";//ç
boolean isFavourite = false;
String imgres = "furoo";
int nr_of_pics = 3;
Item item = new Item(title, author, category, date, type, country, colour, material, isFavourite, imgres, nr_of_pics);
dbHandler.addItem(item);
}
//helper for types
public static final String VARCHAR_TYPE = " VARCHAR(50)";
public static final String BOOL_TYPE = " BOOLEAN";
public static final String INT_TYPE = " INTEGER";
Here it creates the table:
public void onCreate(SQLiteDatabase db) {
String CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS +
"("
+ COLUMN_ENTRY_ID + INT_TYPE +" PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_TITLE + VARCHAR_TYPE + ","
+ COLUMN_AUTHOR + VARCHAR_TYPE + ","
+ COLUMN_CATEGORY + VARCHAR_TYPE + ","
+ COLUMN_DATE + INT_TYPE + ","
+ COLUMN_TYPE + VARCHAR_TYPE + ","
+ COLUMN_COUNTRY + VARCHAR_TYPE + ","
+ COLUMN_COLOUR + VARCHAR_TYPE + ","
+ COLUMN_MATERIAL + VARCHAR_TYPE + ","
+ COLUMN_FAVOURITE + BOOL_TYPE + ","
+ COLUMN_IMGRES + VARCHAR_TYPE + ","
+ COLUMN_NUMBER_OF_PICS + INT_TYPE +
")";
db.execSQL(CREATE_ITEMS_TABLE);
}
Adding item:
public void addItem(Item item) {
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE, item.getItemTitle());
values.put(COLUMN_AUTHOR, item.getAuthor());
values.put(COLUMN_CATEGORY, item.getCategory());
values.put(COLUMN_DATE, item.getDate());
values.put(COLUMN_TYPE, item.getType());
values.put(COLUMN_COUNTRY, item.getCountry());
values.put(COLUMN_COLOUR, item.getColour());
values.put(COLUMN_MATERIAL, item.getMaterial());
values.put(COLUMN_FAVOURITE, item.getFavourite());
values.put(COLUMN_IMGRES, item.getImgres());
values.put(COLUMN_NUMBER_OF_PICS, item.getNumberOfPics());
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE_ITEMS, null, values);
db.close();
}
Here full function for searching nr_of_pics:
public int findPictureNumber(String itemtitle) {
String query = "SELECT nr_of_pics FROM Items WHERE ItemTitle = '" + itemtitle + "'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
int PicsNumber=0;
if (cursor.moveToFirst()) {
cursor.moveToFirst();
PicsNumber=Integer.parseInt(cursor.getString(0));
cursor.close();
return PicsNumber;
} else {
//wtf?
}
db.close();
return 0;
}
And the errors say as follows:
(1) table Items has no column named imgres
Error inserting colour=Castanho/Cortiça author=Fernando Brízio
imgres=furo category=Decoração title=Furo type=Taça date=2012
nr_of_pics=3 material=Castanho/Cortiça is_favourite=false
country=Portugal
android.database.sqlite.SQLiteException: table Items has no column named imgres (code 1): , while
compiling: INSERT INTO
Items(colour,author,imgres,category,title,type,date,nr_of_pics,material,is_favourite,country)
VALUES (?,?,?,?,?,?,?,?,?,?,?)
You do not give any exception but I think you have error in your SQL. You need to use ' instead of ".
Change your query as below.
String query = "SELECT nr_of_pics FROM Items WHERE ItemTitle = '" + itemtitle + "'";
It is clear that you don't have any column that named "imgres"!
You should modify your query
"INSERT INTO Items(colour,author,imgres,category,title,type,date,nr_of_pics,material,is_favourite,country)
VALUES (?,?,?,?,?,?,?,?,?,?,?)"
I would like to check if any row exists within the Sqlite database.
my java class
public static final String DATABASE_TABLE2 = "receivernumber";
public static final String KEY_ROWID2 = "hpnumberID2";
public static final String KEY_NAME2 = "hpNumber2";
public long insertContact2(String hpNumber2)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME2, hpNumber2);
if(CheckIsDataAlreadyInDBorNot(0) == true) {
return db.update(
DATABASE_TABLE2, initialValues, "SET='"+KEY_NAME2+"'" +"WHERE"+ "KEY_ROWID2="+1, null
) > 0;
}
else {
return db.insert(DATABASE_TABLE2, null, initialValues);
}
//if there is alrdy a record, create a method to reject intake
return 0;
}
public boolean CheckIsDataAlreadyInDBorNot(long hpnumberID) {
Cursor mCursor = db.query(
true, DATABASE_TABLE2, new String[] {KEY_ROWID, KEY_NAME},KEY_ROWID + "=" + hpnumberID, null, null, null, null, null
);
String Query = "Select * from " + DATABASE_TABLE2 + " where " + KEY_ROWID2 + " < " + 0;
SQLiteDatabase sqldb = EGLifeStyleApplication.sqLiteDatabase;
Cursor cursor = sqldb.rawQuery(Query, null);
if(cursor.getCount<=0) return false;
return true;
}
public boolean updateContact2(long hpnumberID2, String hpNumber2)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME2, hpNumber2);
//args.put(KEY_NAME3, Selected);
//return db.update(DATABASE_TABLE2, args, KEY_ROWID2 + "=" + hpnumberID2, null) > 0;
//db.execSQL("UPDATE " + DATABASE_TABLE2 + " SET " + KEY_NAME2 + " WHERE " + KEY_ROWID2 + "=1 ");
return db.update(DATABASE_TABLE2, args, "SET='" + KEY_NAME2 + "'" + "WHERE" + "KEY_ROWID2=" + 1, null) > 0;
}
So my database layout is such that the user can only add a number for the first time. Subsequent times the user wishes to add a number, it would be replaced by an edit function instead. However, there's an error called EGLifeStyleApplication cannot be resolved to a variable. However, as this is an answer from questions solved successfully, they did not really explain what is the function of that EGLifeStyleApplications. So how do I go about doing what I want to achieve? (How do I edit my insert statement) Thanks.
Replace the offending line with
sqldb = ctx.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
where ctx is a context you will pass as a parameter to your CheckIsDataAlreadyInDBorNot method. i.e.:
public boolean CheckIsDataAlreadyInDBorNot(Context ctx, long hpnumberID) {
and DB_NAME is a string containing your db name, i.e.:
private final static String DB_NAME = "rec_nums.db";
public static final String DATABASE_TABLE2 = "receivernumber";
public static final String KEY_ROWID2 = "hpnumberID2";
public static final String KEY_NAME2 = "hpNumber2";
I have an SQLite database in an Android app. One database with two tables. simple read in some text and read it out, however, the first of two tables works perfectly and the second table does not and gives errors. I have looked at my code and it seems all correct. I dare anyone to find an error in my code or SQL statements below.
Especially interested in the SQL statements, because my SQL code is PERFECT as far as I know, for both tables, however in the LOGCAT says that a there is no table that I am reading into for table two.
Why would one of my tables work and the other not? Yet they are in the same database and written the same way.
DATABASE OPERATION ON FIRST TABLE; (WORKS PERFECTLY)
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
cv.put(KEY_HITS, hits);
ourDatabase.insert(DATABASE_TABLE_1, null, cv);
public String getData() {
String[] columns = new String[] { KEY_ROWID, KEY_NAME, KEY_HITS };
Cursor c = ourDatabase.query(DATABASE_TABLE_1, columns, null, null, null,
null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iHits = c.getColumnIndex(KEY_HITS);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
result = result + c.getString(iRow) + " " + c.getString(iName)
+ " " + c.getString(iHits) + "\n";
}
return result;
}
ourHelper.close();
DATABASE OPERATION ON SECOND TABLE; (DOES NOT WORK, ERRORS)
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put( KEY_RESULT, result);
return ourDatabase.insert(DATABASE_TABLE_2, null, cv);
public String getData2() {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_ROWID, KEY_RESULT, KEY_TABLET, KEY_DATE };
Cursor c = ourDatabase.query(DATABASE_TABLE_2, columns, null, null, null,
null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iResult = c.getColumnIndex(KEY_RESULT);
int iTablet = c.getColumnIndex(KEY_TABLET);
int iDate = c.getColumnIndex(KEY_DATE);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
result = result + c.getString(iRow) + " " + c.getString(iResult)
+ " " + c.getString(iTablet) + " " + c.getString(iDate) + "\n";
}
return result;
}
ourHelper.close();
LOGCAT OUTPUT;
01-31 19:33:01.670: E/AndroidRuntime(6420): FATAL EXCEPTION: main
01-31 19:33:01.670: E/AndroidRuntime(6420):
java.lang.RuntimeException: Unable to start activity ComponentInfo{DBView}:
android.database.sqlite.SQLiteException: no such column: date: , while compiling:
SELECT _id, game_result, tablet_winner, date FROM prizeTable
MORE CODE FOR DETAILS;
public class PlayGame {
public static final String KEY_ROWID="_id";
// for table 1 gameTable
public static final String KEY_NAME="persons_name";
public static final String KEY_HITS="persons_hits";
// for table 2 prizesTable
public static final String KEY_RESULT="game_result";
public static final String KEY_TABLET="tablet_winner";
public static final String KEY_DATE="date";
private static final String DATABASE_NAME="PlayGamesdb";
private static final String DATABASE_TABLE_1="gameTable";
private static final String DATABASE_TABLE_2="prizeTable";
private static final int DATABASE_VERSION = 1;
private static final String CREATE_TABLE_1 = "CREATE TABLE " + DATABASE_TABLE_1 + " (" + KEY_ROWID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_NAME + " TEXT NOT NULL, " + KEY_HITS + " TEXT NOT NULL);";
private static final String CREATE_TABLE_2 = "CREATE TABLE " + DATABASE_TABLE_2 + " (" + KEY_ROWID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_RESULT + " TEXT NOT NULL, " + KEY_TABLET
+ " TEXT NOT NULL, " + KEY_DATE + "TEXT NOT NULL);";
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
private static class DbHelper extends SQLiteOpenHelper{
public DbHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_1);
db.execSQL(CREATE_TABLE_2);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_1 + "AND" + DATABASE_TABLE_2);
onCreate(db);
}
}
<<< EDIT >>>
Safime's suggestion fixed the crashing, that was adding a space between KEY_DATE and TEXT in the creation of the second table.
However still a problem, no more crashing, but the insert() method is still not working. Getting a -1 return shows that it is not inserting anything, and the the table 2 is still empty after inserting a new row to the table. Got to find out why it is failing to create any new rows in the table. Just like earlier, table one works fine but table two is still not working yet.
You are using Constraint NOT NULL and you are inserting only in one column. You must be getting SQLiteConstraintexception Exception. Try inserting in all columns.
You are missing an empty space after the column KEY_DATE and before TEXT on the creation of the second table.
(...) + KEY_DATE + " TEXT NOT NULL); (...)
Probably you have a problem at the create table statement of your second table. Try to open your db file with the sqlite3 command line tool, and see if this table exits. If not, the problem is in the CREATE statement.