Failing to delete rows from a linked table - sqlite

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.

Related

Referenced foreign key id is null when inserting new values in the second table. How do I simply select the id from the first table to the second?

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");
}

Adding items to a second table SQLite in Android Studio does nothing

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");
}
}

what is function/value for updating a row with current time_stamp in sqlite

This is my create table statement.
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_BRANDS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_CREATED_AT + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ KEY_UPDATED_AT + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" + ")";
as per SQLITE document ON UPDATE CURRENT_TIMESTAMP is not allowed in column definition.
so i thought of passing KEY_UPDATED_AT values while updating a row.
This is my update function.
public int updateBrand(Brand brand) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, brand.getName());
values.put(KEY_UPDATED_AT, ?????)
// updating row
return db.update(TABLE_BRANDS, values, KEY_ID + " = ?",
new String[] { String.valueOf(brand.getId()) });
}
My question is what values should i put values.put(KEY_UPDATED_AT, ?????), to update the row properly.
The ContentValues object allows only literal values.
To do any kind of computation, you must use execSQL instead:
db.execSQL("UPDATE "+TABLE_BRANDS+
" SET "+KEY_NAME+" = ?, "+
KEY_UPDATED_AT+" = CURRENT_TIMESTAMP"+
" WHERE "+KEY_ID+" = ?",
new Object[]{ brand.getName(), brand.getId() });

Android Sqlite Create syntax error

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" + ")";

SQlite create table error on Android

//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

Resources