//Table names
public static final String TABLE_SUBJECTS = "SUBJECTS";
public static final String TABLE_TIMETABLE = "TIMETABLE";
public static final String TABLE_ATTENDANCE = "ATTENDANCE";
//Column names
public static final String COLUMN_SUBJECTS_SUBJECT = "SUBJECT"; //Subjects
public static final String COLUMN_TIMETABLE_SUBJECT = "SUBJECT"; //Timetable
public static final String COLUMN_TIMETABLE_PERIOD = "PERIOD";
public static final String COLUMN_TIMETABLE_DAY = "DAY";
public static final String COLUMN_ATTENDANCE_SUBJECT = "SUBJECT";
//Attendance
public static final String COLUMN_ATTENDANCE_ATTENDED = "ATTENDED";
public static final String COLUMN_ATTENDANCE_TOTAL = "TOTAL";
public static final String COLUMN_ATTENDANCE_PERCENTAGE = "PERCENTAGE";
//Queries
private static final String SQL_CREATE_TABLE_TIMETABLE = "create table " + TABLE_TIMETABLE + "(" +
COLUMN_TIMETABLE_SUBJECT + " text, " +
COLUMN_TIMETABLE_PERIOD + " integer, " +
COLUMN_TIMETABLE_DAY + " text, " +
"PRIMARY KEY " + "(" +
COLUMN_TIMETABLE_PERIOD + "," +
COLUMN_TIMETABLE_DAY + "), " +
"FOREIGN KEY " + "(" + COLUMN_TIMETABLE_SUBJECT + ") " +
"REFERENCES " + TABLE_SUBJECTS + " (" + COLUMN_SUBJECTS_SUBJECT +
")" + ");";
private static final String SQL_CREATE_TABLE_ATTENDANCE = "create table " + TABLE_ATTENDANCE + "(" +
COLUMN_ATTENDANCE_SUBJECT + " text, " +
COLUMN_ATTENDANCE_ATTENDED + " integer, " +
COLUMN_ATTENDANCE_TOTAL + " integer, " +
COLUMN_ATTENDANCE_PERCENTAGE + " integer, " +
"PRIMARY KEY " + "(" + COLUMN_ATTENDANCE_SUBJECT + "), " +
"FORIEGN KEY " + "(" + COLUMN_ATTENDANCE_SUBJECT + ") " +
"REFERENCES " + TABLE_SUBJECTS + " (" + COLUMN_SUBJECTS_SUBJECT + ")" +
");";
So, I'm trying to program an android app using SQLite of course. I'm running into a problem trying to create the "ATTENDANCE" table.
It says "syntax error near "FOREIGN" ". Now, I don't get this because, as you can see I have created the "TIMETABLE" table successfully and in the "ATTENDANCE" table too followed more or less the same syntax.
I've even tried commenting out the Foreign key. It works fine with just the primary key constraint, but when I couple it with the foreign key constraint the error shows up again. If I comment out the primary key part, with only the foreign key constraint, then it says "syntax error near "SUBJECT" ". So, please help.
You have a typo in your SQL_CREATE_TABLE_ATTENDANCE String. FOREIGN KEY is incorrectly written FORIEGN KEY
Related
I have created two tables in my Database Manager
#Override
public void onConfigure(SQLiteDatabase db) {
db.setForeignKeyConstraintsEnabled(true);
super.onConfigure(db);
}
#Override
public void onCreate(SQLiteDatabase database)
{
database.setForeignKeyConstraintsEnabled(true);
// create table
String sql = "create table "
+ TABLE_NAME + " ("
+ C_LIST_ID + " integer primary key autoincrement, "
+ C_LIST_NAME + " VARCHAR(255))";
Log.d(TAG, "in onCreate");
//create second table
String sql2 = "create table "
+ TABLE_NAME_ITEMS + " ("
+ C_LIST_ITEM + " VARCHAR(255), "
+ C_DATE + " text, "
+ C_FLAG + " integer, "
+ C_LIST_NAME + " VARCHAR(255), "
+ C_ITEM_ID + " integer, foreign key "
+ "("+C_ITEM_ID+")" + " references " +TABLE_NAME+ "("+C_LIST_ID+"))";
Log.d(TAG, "in onCreate second database");
database.execSQL(sql);
database.execSQL(sql2);
}
This is how I am inserting the data into the second table. In the tables themselves, the foreign key IDs are null. How do I bring the id from the first table to the second when creating a new item with the same C_LIST_NAME?
public void insertItemData(String item, String listName)
{
Integer listNameId = getListId(listName);
database = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(C_LIST_ITEM, item + listNameId);
contentValues.put(C_LIST_NAME, listName);
database.insertOrThrow(TABLE_NAME_ITEMS, null , contentValues);
Log.d(TAG, "insertData: data has been inserted in items");
}
I should've rested last night after trying to figure this out for hours.
I figured it out and the solution was very simple. I was just too tired to think I guess.
In case anyone is curious, I just need to insert it like this:
public void insertItemData(String item, String itemDescription, String listName)
{
baseActivity = new BaseActivity();
database = getWritableDatabase();
database.execSQL("INSERT INTO "+TABLE_NAME_ITEMS+
"("+C_ITEM_NAME+"," +C_ITEM_DESCRIPTION+ ", " +C_LIST_NAME+ "," +C_DATE+ "," +C_FLAG+ "," +C_ITEM_ID+ ")"
+ "VALUES ('"+item+ "', '"+itemDescription+ "', '" +listName+ "', '" +baseActivity.getCurTime()+ "', '" +0+ "', "
+ "(SELECT " +C_LIST_ID+ " FROM " +TABLE_NAME+ " WHERE "
+C_LIST_NAME+ "=?))",
new Object[]{listName});
Log.d(TAG, "insertData: data has been inserted in items");
}
can anyone work out what is wrong with this code? I'm getting cannot resolve error and both foreign key and references are in red.
private static final String CREATE_TABLE_EXPENSES = "CREATE TABLE " + TABLE_EXPENSES
+ " (" + COL_ID + " INTEGER PRIMARY KEY," + COL_EXPENSES_SOURCE + " TEXT,"
+ COL_EXPENSES_AMOUNT + "NUMERIC," + COL_DATE + "DATE," + COL_DESCRIPTION + "TEXT," +
COL_FOREIGN_KEY_CATEGORY + " INTEGER, "+ FOREIGN_KEY ("+COL_FOREIGN_KEY_CATEGORY+")
REFERENCES "+DatabaseManager.TABLE_CATEGORY+"("+COL_ID+"));";
The answer was purely about adding spaces between some of the + and attributes.
I think my problem is simple and I'm not being able to see the solution, but, when I add data to my second table it does nothing but showing the Toast that it is not working.
This is my DatabaseHelper.java:
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " ( " + COL1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL2 + " TEXT);";
String createTable2 = "CREATE TABLE " + TABLE_NAME2 + " ( " + COL3 + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COL4 + " TEXT,"
+ COL5 + " INTEGER," + COL1 + " INTEGER PRIMARY KEY," + COL6 + " TEXT, " + " FOREIGN KEY (" + COL1 + ") REFERENCES "
+ TABLE_NAME + "(" + COL1 + "));";
db.execSQL(createTable);
db.execSQL(createTable2);
}
public boolean addData2(String newEntry1, String newEntry2, String horarios, Integer id_ppl) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL4, newEntry1);
contentValues.put(COL5, newEntry2);
contentValues.put(COL1, id_ppl);
contentValues.put(COL6, horarios);
long result = db.insert(TABLE_NAME2, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
This is my mainactivity.java
buttonNewPill.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newEntry1 = editText2.getText().toString();
String newEntry2 = editText3.getText().toString();
String textSp1 = spinner2.getSelectedItem().toString();
String textSp2 = spinner3.getSelectedItem().toString();
String horario = textSp1 + ":" + textSp2;
Integer id_ppl = 1;
Toast.makeText(getApplicationContext(), "horario is "+ horario, Toast.LENGTH_LONG).show();
/*
Toast.makeText(getApplicationContext(), "text is "+ textSp, Toast.LENGTH_LONG).show();
*/
if (editText2.length() > 0 && editText3.length() > 0){
AddData2(newEntry1, newEntry2, horario, id_ppl);
editText2.setText("");
editText3.setText("");
} else {
toastMessage("Isn't your field empty?");
}
}
});
private void AddData2(String newEntry1, String newEntry2, String horario, Integer id_ppl) {
boolean insertData = mDatabaseHelper.addData2(newEntry1, newEntry2, horario, id_ppl);
if (insertData){
toastMessage("Data Succesfully entered");
} else {
toastMessage("Oops! Something went wrong");
}
}
All classes are well acommodated, the contructors were made, and it doesn't have any syntaxes error (I think), since it lets me execute my app in my telephone. But I got the problem described above.
Thank you very much for your time and assistance in this matter.
Your, I believe, issue is that you are trying to define multiple PRIMARY INDEXES for the 2nd table.
That is you have :-
for COL3 INTEGER PRIMARY KEY AUTOINCREMENT
for COL1 INTEGER PRIMARY KEY
You can only have a single PRIMARY INDEX (you can have multiple non-primary indexes).
If you looked at the log, you would have had something similar to (when you first ran):-
05-11 01:38:10.133 1215-1215/? E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{soanswers.soanswers/soanswers.soanswers.MainActivity}: android.database.sqlite.SQLiteException: table "tbl002" has more than one primary key (code 1): , while compiling: CREATE TABLE tbl002 ( column3 INTEGER PRIMARY KEY AUTOINCREMENT, column4 TEXT,column5 INTEGER,column1 INTEGER PRIMARY KEY,column6 TEXT, FOREIGN KEY (column1) REFERENCES tbl001(column1));
So at a guess you would want :-
String createTable2 = "CREATE TABLE " + TABLE_NAME2 + " ( " +
COL3 + " INTEGER PRIMARY KEY, " +
COL4 + " TEXT,"
+
COL5 + " INTEGER," +
COL1 + " INTEGER," +
COL6 + " TEXT, " +
" FOREIGN KEY (" + COL1 + ") REFERENCES " + TABLE_NAME + "(" + COL1 + "));";
Column 1 removed as primary index, although you may want an additional index on COL1 as it references another table.
You very likely don't really want AUTOINCREMENT, as per
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and
disk I/O overhead and should be avoided if not strictly needed. It is
usually not needed.SQLite Autoincrement
Note that you will need to delete the App's Data or uninstall the App (as long as you can afford to lose any existing data) after making the changes, for the changes to be applied
- There are other ways but this is the simplest.
Adding the Index (optional):-
The following would add an additional index according to table2 col1 :-
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " ( " + COL1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL2 + " TEXT);";
/*
String createTable2 = "CREATE TABLE " + TABLE_NAME2 + " ( " + COL3 + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COL4 + " TEXT,"
+ COL5 + " INTEGER," + COL1 + " INTEGER PRIMARY KEY," + COL6 + " TEXT, " + " FOREIGN KEY (" + COL1 + ") REFERENCES "
+ TABLE_NAME + "(" + COL1 + "));";
*/
String createTable2 = "CREATE TABLE " + TABLE_NAME2 + " ( " +
COL3 + " INTEGER PRIMARY KEY, " +
COL4 + " TEXT,"
+
COL5 + " INTEGER," +
COL1 + " INTEGER," +
COL6 + " TEXT, " +
" FOREIGN KEY (" + COL1 + ") REFERENCES " + TABLE_NAME + "(" + COL1 + "));";
String crtTable2Col1Index = "CREATE INDEX IF NOT EXISTS col1index ON " +
TABLE_NAME2 + "(" + COL1 + ")"; //<<<< ADDED
db.execSQL(createTable);
db.execSQL(createTable2);
db.execSQL(crtTable2Col1Index); //<<<< ADDED
}
col1index would be the name of the index
Additional
Note as you intend to utilise FOREIGN KEYS you will need to enable FOREIGN KEYS (if you haven't). You can do this by overriding the onConfigure method e.g. :-
#Override
public void onConfigure (SQLiteDatabase db) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
db.setForeignKeyConstraintsEnabled(true);
} else {
db.execSQL("pragma foreign_keys = ON");
}
}
I can't seem to find out what exactly I did wrong here. Seem to be getting a syntax error in my create command inside the createNewTable method.
Android SQLite Insert Error (Syntax error code 1)
I've added my database code:
private static final String KEY_DATE = "date";
private static final String KEY_TIME_IN = "timeCheckIn";
private static final String KEY_TIME_OUT = "timeCheckOut";
private static final String KEY_LATITUDE_IN = "latCheckIn";
private static final String KEY_LONGITUDE_IN = "longCheckIn";
private static final String KEY_LATITUDE_OUT = "latCheckOut";
private static final String KEY_LONGITUDE_OUT = "longCheckOut";
public void createNewTable(){
SQLiteDatabase db = this.getWritableDatabase(int _id);
Log.v("Database", "Adding Check in table: " + _id);
String CREATE_TABLE = " CREATE TABLE " + Integer.toString(_id) + "("
+ KEY_DATE + " TEXT," + KEY_TIME_IN + " TEXT," + KEY_TIME_OUT + " TEXT,"
+ KEY_LATITUDE_IN + " REAL," + KEY_LONGITUDE_IN + " REAL," + KEY_LATITUDE_OUT + " REAL,"
+ KEY_LONGITUDE_OUT + " REAL" + ")";
db.execSQL(CREATE_TABLE);}
My logcat error is as follows:
Caused by: android.database.sqlite.SQLiteException: near "1": syntax error (code 1): , while compiling: CREATE TABLE 1(date TEXT,timeCheckIn TEXT,timeCheckOut TEXT,latCheckIn REAL,longCheckIn REAL,latCheckOut REAL,longCheckOut REAL)
You have a table name that starts with a number. Not sure if SQLite allows it, but in MySQL, if your table name is a number, then for every query, you need to specify the table number with double quotes. Try giving the table name a prefix
SQLite is telling you unescaped table names are not allowed to start with a number, in this case the number 1. If you want to use numbers you must escape the table name with brackets, like so
String CREATE_TABLE = " CREATE TABLE [" + Integer.toString(_id) + "] ("
+ KEY_DATE + " TEXT," + KEY_TIME_IN + " TEXT," + KEY_TIME_OUT + " TEXT,"
+ KEY_LATITUDE_IN + " REAL," + KEY_LONGITUDE_IN + " REAL," + KEY_LATITUDE_OUT + " REAL,"
+ KEY_LONGITUDE_OUT + " REAL" + ")";
I have problems deleting the rows from a table.
I have 2 tables with the following definition:
private static final String DATABASE_TABLEELEMENTS = "elements";
public static final String KEY_ROWELEMENTID = "_id";
public static final String KEY_STUDYID = "idstudy";
public static final String KEY_ELEMENTCODE = "code_element";
public static final String KEY_ELEMENTNAME = "description_element";
private static final String DATABASE_TABLETIME = "times";
public static final String KEY_ROWTIME = "_id";
public static final String KEY_ELEMENTID = "idelement";
public static final String KEY_HOURDATE = "hour_date";
public static final String KEY_OBSERVEDYTIME = "observedtime";
public static final String KEY_OBSERVEDACTIVITY = "observedactivity";
both tables are related:
elements._id = times.idelement
I want to delete all rows in table "times" which has the "idstudy" from table "elements" that the user has selected:
For this I created the following function:
public void ResetDataStudies(String selectedid) {
String querytimes = "DELETE FROM "
+ "times"
+ " WHERE "
+ "times.idelement"
+ " IN "
+ "(SELECT "
+ "elements._id"
+ " FROM "
+ "elements"
+ " WHERE "
+ "elements.idstudy = ?)";
ourDatabase.rawQuery(querytimes, new String[] { selectedid });
}
I don't receive a specific error, but after executing it the data has not been deleted.
See below the data type:
db.execSQL(" CREATE TABLE " + DATABASE_TABLEELEMENTS + " (" +
KEY_ROWELEMENTID + " INTEGER UNIQUE PRIMARY KEY AUTOINCREMENT, " +
KEY_ELEMENTCODE + " INTEGER NOT NULL, " +
KEY_ELEMENTNAME + " TEXT, " +
KEY_STUDYID + " TEXT NOT NULL REFERENCES " + DATABASE_TABLEACOUNT + "("+ KEY_ROWSTUDYID +") ON DELETE CASCADE ");
db.execSQL(" CREATE TABLE " + DATABASE_TABLETIME + " (" +
KEY_ROWTIME + " INTEGER UNIQUE PRIMARY KEY AUTOINCREMENT, " +
KEY_HOURDATE + " INTEGER NOT NULL, " +
KEY_OBSERVEDYTIME + " TEXT NOT NULL, " +
KEY_OBSERVEDACTIVITY + " TEXT NOT NULL, " +
KEY_ELEMENTID + " TEXT NOT NULL REFERENCES " + DATABASE_TABLEELEMENTS + "("+ KEY_ROWELEMENTID +") ON DELETE CASCADE ");
}
I have updated my statements but now I receive an error while creating the tables:
error near cascade statement
When you create the table, the foreign key needs to be ON DELETE CASCADE. e.g.
FOREIGN KEY ("+KEY_ELEMENTID+") REFERENCES "+DATABASE_TABLEELEMENTS+" ("+KEY_ROWELEMENTID+") ON DELETE CASCADE); "
You'll also have to tell SQLite to enforce foreign keys (otherwise they are ignored).
PRAGMA foreign_keys = ON;
See https://www.sqlite.org/foreignkeys.html.