SQLite: select from column by month - java

I am trying to sum a tablecolumn on basis of month but I got the following exception:
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
the function
public static float test(SQLiteDatabase db) {
String expenditure = MyDatabaseContract.TableExpenditure.ATTR_EXPENDITURE;
String table = MyDatabaseContract.TableExpenditure.TABLE_EXPENDITURE;
String date = MyDatabaseContract.TableExpenditure.ATTR_DATE;
String query = "SELECT SUM(" + expenditure + ") FROM " + table + " WHERE strftime('%m', date)=11";
Cursor cursor = db.rawQuery(query, null);
float total = 0;
if (cursor.moveToFirst())
total = cursor.getInt(cursor.getColumnIndex("Total"));// get final total
return total;
}
the table
public static class TableExpenditure {
public static final String TABLE_EXPENDITURE = "expenditure_table";
public static final String ATTR_PRIMARY_KEY = "pk_expendituretable";
public static final String ATTR_DATE = "date";
public static final String ATTR_CATEGORY = "category";
public static final String ATTR_EXPENDITURE = "expenditure";
public static final String ATTR_COMMENT = "comment";
public static final int N_COLUMNS = 5;
public static final String SQL_CREATE_TABLE =
"CREATE TABLE " + TABLE_EXPENDITURE + "(" + ATTR_PRIMARY_KEY + " INTEGER PRIMARY KEY AUTOINCREMENT," + ATTR_DATE + " DATE," + ATTR_CATEGORY + " TEXT," +
ATTR_EXPENDITURE + " REAL," + ATTR_COMMENT + " TEXT" + ")";
}
In the debugger the cursor contains one item but when calling getInt(..) the app crashes

The column created for this result:
SUM(" + expenditure + ")
is not called Total.
Change the sql statement to this:
String query = "SELECT SUM(" + expenditure + ") AS Total FROM " + table + " WHERE strftime('%m', date)=11";
This way you give the name (alias) Total to the column.
Or since there is only 1 column returned, do this:
total = cursor.getInt(0);

Related

Android Studio - Error Code:1 (SQLITE_ERROR) Caused By: SQL(query) error missing database

Have the following error message:
Operation failed: table medicine has no column nameed amount(code1):, while compiling: INSERT INTO medicine(name,amount,type,info,registration_no)VALUES(?,?,?,?,?)
Config file:
public class Config {
public static final String COLUMN_MEDICINE_ID = "_id";
public static final String COLUMN_MEDICINE_NAME = "name";
public static final String COLUMN_MEDICINE_PRODUCT = "registration_no";
public static final String COLUMN_MEDICINE_INFO = "info";
public static final String COLUMN_MEDICINE_TYPE = "type";
public static final String COLUMN_MEDICINE_AMOUNT = "amount";
}
Helper File:
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_MEDICINE_TABLE = "CREATE TABLE " + Config.TABLE_MEDICINE + "("
+ Config.COLUMN_MEDICINE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ Config.COLUMN_MEDICINE_NAME + " TEXT NOT NULL, "
+ Config.COLUMN_MEDICINE_PRODUCT + " INTEGER NOT NULL UNIQUE, "
+ Config.COLUMN_MEDICINE_INFO + " TEXT, " //nullable
+ Config.COLUMN_MEDICINE_TYPE + " TEXT " //nullable
+ Config.COLUMN_MEDICINE_AMOUNT + " INTEGER UNIQUE, "
+ ")";
Logger.d("Table create SQL: " + CREATE_MEDICINE_TABLE);
db.execSQL(CREATE_MEDICINE_TABLE);
Logger.d("DB created!");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + Config.TABLE_MEDICINE);
onCreate(db);
}
You forgot a comma between type and amount columns in the create SQL. Additionally there's a stray comma after the amount column def:
+ Config.COLUMN_MEDICINE_TYPE + " TEXT " //nullable
+ Config.COLUMN_MEDICINE_AMOUNT + " INTEGER UNIQUE, "
+ ")";
After fixing the SQL there, you can uninstall your app once to retrigger onCreate().

How do I add a foreign key to a Table in SQLite?

I have created two tables called TermTable and CourseTable. I want CourseTable to have a foreign key to reference TermTable.
This is the code where I create the tables:
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TermDbSchema.TermTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.TermTable.Cols.UUID + ", " +
TermDbSchema.TermTable.Cols.TITLE + ", " +
TermDbSchema.TermTable.Cols.START_DATE + ", " +
TermDbSchema.TermTable.Cols.END_DATE +
")"
);
//I want to give CourseTable a foreign key to reference TermTable^^
db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.CourseTable.Cols.UUID + ", " +
TermDbSchema.CourseTable.Cols.TITLE + ", " +
TermDbSchema.CourseTable.Cols.START_DATE + ", " +
TermDbSchema.CourseTable.Cols.END_DATE + ", " +
TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_EMAIL +
")"
);
}
This is the code Schema code:
public class TermDbSchema {
public static final class TermTable {
public static final String NAME = "terms";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String START_DATE = "startdate";
public static final String END_DATE = "enddate";
}
}
public static final class CourseTable {
public static final String NAME = "courses";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String START_DATE = "startdate";
public static final String END_DATE = "enddate";
public static final String COURSE_STATUS = "coursestatus";
public static final String OPTIONAL_NOTE = "optionalnote";
public static final String MENTOR_NAME = "mentorname";
public static final String MENTOR_PHONE = "mentorphone";
public static final String MENTOR_EMAIL = "mentoremail";
}
}
How do I add a foreign key to CourseTable so that it can reference TermTable?
Change the CourseTable to have another column for the reference (link, relationship, association, mapping are all other terms) :-
public static final class CourseTable {
public static final String NAME = "courses";
public static final class Cols {
public static final String UUID = "uuid";
public static final String TITLE = "title";
public static final String START_DATE = "startdate";
public static final String END_DATE = "enddate";
public static final String COURSE_STATUS = "coursestatus";
public static final String OPTIONAL_NOTE = "optionalnote";
public static final String MENTOR_NAME = "mentorname";
public static final String MENTOR_PHONE = "mentorphone";
public static final String MENTOR_EMAIL = "mentoremail";
public static final String TERM_LINK = "termlink" //<<<<<<<<<< ADDED
}
the column name could of course be what you wish
Change the Creating SQL for the courses table to add the Foreign Key constraint.
db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.CourseTable.Cols.UUID + ", " +
TermDbSchema.CourseTable.Cols.TITLE + ", " +
TermDbSchema.CourseTable.Cols.START_DATE + ", " +
TermDbSchema.CourseTable.Cols.END_DATE + ", " +
TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_EMAIL + ", " + //<<<<<<<<<< CHANGED
TermDbSchema.CourseTable.Cols.TERM_LINK + " INTEGER REFERENCES " + TermDbSchema.TermTable.NAME + "(_id)" + //<<<<<<<<<< ADDED
")"
);
you may wish to adhere to your convetions an omit INTEGER (the type affinity of the column), that would not be an issue. It has been included because most would specifiy column types rather than have the default (NUMERIC) applied.
Important
Then override the onConfigure to call the setForeignKeyConstraintsEnabled passing true.
e.g. :-
#Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
By default Foreign Key Support is turned off, making the above coding changes will be useless unless Foreign Key Support is turned on.
You will need to then do 1 of the following :-
Delete the App's data
Uninstall the App
and then rerun the App.
Note any existing data will be lost. If you need to retain data then that could be relatively complicated.
Foreign Keys
Note that defining a foreign key is ONLY defining a constraint (rule) that requires the value being placed into the column that has the constraint to be a value in one of the rows of the parent table/column that is referenced.
Defining a Foreign Key constraint DOES NOT automatically make relationships happen. That is you will still have to determine the related term when adding a course (a common misconception is that it does this).
You may wish to consider extending the definition to include ON DELETE and ON UPDATE actions, such as CASCADE. e.g. ON DELETE CASCADE would, when a(if) term row is deleted, deleted the child rows in the course table. Likewise ON UPDATE CASCADE will update the referenced value of the children in the course table should that value be changed in the term table (these can make life simpler).
e.g. you could use :-
TermDbSchema.CourseTable.Cols.TERM_LINK + " INTEGER REFERENCES " + TermDbSchema.TermTable.NAME + "(_id) ON DELETE CASCADE ON UPDATE CASCADE" + //<<<<<<<<<< ADDED
You may wish to refer to SQLite Foreign Key Support
Define a string inside class Cols of class CourseTable which will hold the name of this new column like:
public static final String TERM_ID = "term_id";
Change the CREATE statement of the table CourseTable:
db.execSQL("create table " + TermDbSchema.CourseTable.NAME + "(" +
"_id integer primary key autoincrement, " +
TermDbSchema.CourseTable.Cols.UUID + ", " +
TermDbSchema.CourseTable.Cols.TITLE + ", " +
TermDbSchema.CourseTable.Cols.START_DATE + ", " +
TermDbSchema.CourseTable.Cols.END_DATE + ", " +
TermDbSchema.CourseTable.Cols.COURSE_STATUS + ", " +
TermDbSchema.CourseTable.Cols.OPTIONAL_NOTE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_NAME + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_PHONE + ", " +
TermDbSchema.CourseTable.Cols.MENTOR_EMAIL + ", " +
TermDbSchema.CourseTable.Cols.TERM_ID + " INTEGER, " +
"FOREIGN KEY (" + TermDbSchema.CourseTable.Cols.TERM_ID +
") REFERENCES " + TermDbSchema.TermTable.NAME + "(_id)" +
")"
);
This new column will reference the column _id which is the PRIMARY KEY of TermTable.
You need to uninstall the app from the device so the database is deleted and then rerun to recreate the database.

table (table name) has no column named (column name) [duplicate]

This question already has answers here:
android.database.sqlite.SQLiteException: table X has no column named Y: , while compiling: INSERT INTO
(9 answers)
Database table doesn't exist according to android studio compiler
(1 answer)
When does SQLiteOpenHelper onCreate() / onUpgrade() run?
(15 answers)
Closed 5 years ago.
First of all, I tried other solutions but they didn't work for me.
this is the how I create the table:
String CREATE_DETAILS_TABLE = "CREATE TABLE " + TABLE_DETAIL + "("
+ STATUS + " TEXT," + FIRST_NAME + " TEXT," + LAST_NAME + " TEXT," + EMAIL + " TEXT," + COUNTRY
+ " TEXT," + COUNTRYALPHA2 + " TEXT," + CITY + " TEXT," + ZIP + " TEXT," + ADDRESS
+ " TEXT," + USERACCSTATUS + " TEXT," + SKYPENAME + " TEXT," + COUNTRY_NAME + " TEXT," +
PHONE_CODE + " TEXT," + PHONE + " TEXT," + DEVICEID + " TEXT," + STATUSDESC + " TEXT" + ")";
db.execSQL(CREATE_DETAILS_TABLE);
the columns and name:
private static final String TABLE_DETAIL = "detail";
// Details table columns
private static final String STATUS = "Status";
private static final String FIRST_NAME = "FirstName";
private static final String LAST_NAME = "LastName";
private static final String EMAIL = "Email";
private static final String COUNTRY= "Country";
private static final String COUNTRYALPHA2= "CountryAlpha2";
private static final String CITY= "City";
private static final String ZIP = "Zip";
private static final String ADDRESS = "Address";
private static final String USERACCSTATUS = "UserAccStatus";
private static final String SKYPENAME = "SkypeName";
private static final String COUNTRY_NAME = "CountryName";
private static final String PHONE_CODE = "Phonecode";
private static final String PHONE = "Phone";
private static final String DEVICEID = "DeviceIdentificator";
private static final String STATUSDESC = "StatusDescription";
adding the details to the table:
public void addDetails(String status,String firstName,String lastName,String email
,String country,String countryAlpha2,String city,String zip,String address,String userAccStatus
,String skypename,String phonecode,String phone,String countryname,String deviceid,String statusDesc){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(STATUS,status);
contentValues.put(FIRST_NAME,firstName);
contentValues.put(LAST_NAME,lastName);
contentValues.put(EMAIL,email);
contentValues.put(COUNTRY,country);
contentValues.put(COUNTRYALPHA2,countryAlpha2);
contentValues.put(CITY,city);
contentValues.put(ZIP,zip);
contentValues.put(ADDRESS,address);
contentValues.put(USERACCSTATUS,userAccStatus);
contentValues.put(SKYPENAME,skypename);
contentValues.put(PHONE_CODE,phonecode);
contentValues.put(PHONE,phone);
contentValues.put(COUNTRY_NAME,countryname);
contentValues.put(DEVICEID,deviceid);
contentValues.put(STATUSDESC,statusDesc);
long id = db.insert(TABLE_DETAIL,null,contentValues);
db.close();
Log.d(TAG,"User Details added into sqlite: " + id);
}
and it gives me this error when trying to add the details :
android.database.sqlite.SQLiteException: table detail has no column
named StatusDescription (code 1): , while compiling: INSERT INTO
detail(Status,Zip,Email,Address,UserAccStatus,CountryName,FirstName,City,SkypeName,Phone,StatusDescription,Phonecode,Country,LastName,CountryAlpha2,DeviceIdentificator)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
I'm new to all of this and if someone could help me find whats causing the problem it would be great!
The message says you don’t have a column named StatusDescription. Are you sure the name is correct ?

Error while inserting data in sqlite db in android [duplicate]

i'm still learning Android development, And i have a problem creating an sqlite database table. here is a part of my code :
`
private static final String CREATE_ADS_PICTURE = "CREATE TABLE "
+ AdsBDD.TABLE_ADS_PICTURE + "(" + AdsBDD.ID_PICS
+ " INTEGER PRIMARY KEY AUTOINCREMENT ," + AdsBDD.AD_ID
+ " INTEGER NOT NULL," + AdsBDD.PICTURE + " TEXT," + AdsBDD.FOLDER
+ " TEXT," + AdsBDD.ORDER_NO + " INTEGER NOT NULL);";
private static final String CREATE_AGENCES = "CREATE TABLE "
+ AgencesBDD.TABLE_AGENCES + "(" + AgencesBDD.ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + AgencesBDD.GROUP
+ " INTEGER," + AgencesBDD.USERNAME + " TEXT," + AgencesBDD.EMAIL
+ " TEXT," + AgencesBDD.CONTACT_NAME + " TEXT,"
+ AgencesBDD.REGISTRATION_DATE + " TEXT," + AgencesBDD.ACTIVATION
+ " TEXT," + AgencesBDD.ACTIVE + " INTEGER," + AgencesBDD.STORE
+ " INTEGER," + AgencesBDD.STORE_BANNER + " TEXT,"
+ AgencesBDD.RATING + " REAL," + AgencesBDD.LANGUAGE + " TEXT,"
+ AgencesBDD.IDENTITY + " TEXT," + AgencesBDD.ADDRESS + " TEXT,"
+ AgencesBDD.PHONE + " TEXT," + AgencesBDD.COMPANY + " TEXT,"
+ AgencesBDD.WEBPAGE + " TEXT," + AgencesBDD.CODE_POSTAL + " TEXT,"
+ AgencesBDD.JE_SUIS_UN + " TEXT," + AgencesBDD.VILLE + " TEXT,"
+ AgencesBDD.VIDEO + " TEXT);";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_ADS_PICTURE);
db.execSQL(CREATE_AGENCES);
}
public class AgencesBDD {
public static final String TABLE_AGENCES = "agences";
public static final String ID = "id";
public static final String GROUP = "group";
public static final String USERNAME = "username";
public static final String EMAIL = "email";
public static final String CONTACT_NAME = "contact_name";
public static final String REGISTRATION_DATE = "registration_date";
public static final String ACTIVATION = "activation";
public static final String ACTIVE = "active";
public static final String STORE = "store";
public static final String STORE_BANNER = "store_banner";
public static final String RATING = "rating";
public static final String LANGUAGE = "language";
public static final String IDENTITY = "identity";
public static final String ADDRESS = "address";
public static final String PHONE = "phone";
public static final String COMPANY = "company";
public static final String WEBPAGE = "webpage";
public static final String CODE_POSTAL = "code_postal";
public static final String JE_SUIS_UN = "je_suis_un";
public static final String VILLE = "ville";
public static final String VIDEO = "video";
`
So the problem is that Sqlite throws this exception for the table AGENCES, but the Table AD_PICTURE works fine:
03-08 14:36:01.892: E/AndroidRuntime(10822): FATAL EXCEPTION: main
03-08 14:36:01.892: E/AndroidRuntime(10822): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.infonetdiffusion.immohabitation/com.infonetdiffusion.immohabitation.FragmentBaseActivity}: android.database.sqlite.SQLiteException: near "group": syntax error (code 1): , while compiling: CREATE TABLE agences(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,group INTEGER,username TEXT,email TEXT,contact_name TEXT,registration_date TEXT,activation TEXT,active INTEGER,store INTEGER,store_banner TEXT,rating REAL,language TEXT,identity TEXT,address TEXT,phone TEXT,company TEXT,webpage TEXT,code_postal TEXT,je_suis_un TEXT,ville TEXT,video TEXT);
it should be easy to fix, but i can't find where i'm wrong...
any help would be apreciated!
you are using sqlite keyword as column name i.e. group sqliteKeyword which is restrict
Drop the NOT NULL for the id column.
Read here
Those two cases are not equivalent! Note that primary key in first case doesn't have NOT NULL.
CREATE TABLE agences(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,group INTEGER,username TEXT,email TEXT,contact_name TEXT,registration_date TEXT,activation TEXT,active INTEGER,store INTEGER,store_banner TEXT,rating REAL,language TEXT,identity TEXT,address TEXT,phone TEXT,company TEXT,webpage TEXT,code_postal TEXT,je_suis_un TEXT,ville TEXT,video TEXT);
group is a key word in sql, you can't use it as a column name, change group to other strings that can't be key word in sql

Problems when INSERT into DB

When I try to submit data into the database, the app crashes.
Here are the parts of the java file concerned with creating and inserting data into the database.
My Contract.java class has the following information:
public class Contract {
public static abstract class customReminder{
public static final String TABLE_NAME = "CUSTOM_REMINDER";
public static final String ID = "ID";
public static final String TITLE = "TITLE";
public static final String DESCRIPTION = "DESCRIPTION";
public static final String DATE_TIME = "DATE_TIME";
public static final String[] REMINDER_COLUMNS = {ID, TITLE, DESCRIPTION, DATE_TIME};
}
My DBHelper.java class:
//SQLite statement for custom reminder table
public static final String CUSTOM_REMINDER_TABLE = "CREATE TABLE " + Contract.customReminder.TABLE_NAME + "("
+ Contract.customReminder.ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Contract.customReminder.TITLE + " TEXT,"
+ Contract.customReminder.DESCRIPTION + " TEXT,"
+ Contract.customReminder.DATE_TIME + " TEXT,"
+ ");";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CUSTOM_REMINDER_TABLE);
}
My CustumRemider.java class:
public boolean createCustomReminder(String title, String description, String dateTime){
ContentValues contentValues = new ContentValues();
contentValues.put(mAllColumns[1], title);
contentValues.put(mAllColumns[2], description);
contentValues.put(mAllColumns[3], dateTime);
long result = mDatabase.insert(Contract.customReminder.TABLE_NAME, null, contentValues);
return result != -1;
}
I downloaded the database to my PC from Android Device Monitor and opened it with SQLiteBrowser. I notice that a table android_metadata is created instead of CUSTOM_REMINDER.
CREATE TABLE android_metadata (locale TEXT)
I neither know where the query comes from nor why it does this.
You need to change
delete comma (",") after last parameter in create table query
public static final String CUSTOM_REMINDER_TABLE = "CREATE TABLE " + Contract.customReminder.TABLE_NAME + "("
+ Contract.customReminder.ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Contract.customReminder.TITLE + " TEXT,"
+ Contract.customReminder.DESCRIPTION + " TEXT,"
+ Contract.customReminder.DATE_TIME + " TEXT"
+ ");";
instead of this
public static final String CUSTOM_REMINDER_TABLE = "CREATE TABLE " + Contract.customReminder.TABLE_NAME + "("
+ Contract.customReminder.ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Contract.customReminder.TITLE + " TEXT,"
+ Contract.customReminder.DESCRIPTION + " TEXT,"
+ Contract.customReminder.DATE_TIME + " TEXT,"
+ ");";

Categories