Foreign key constraints not working in sqlite android studio - java

I have two tables. TABLE_ADD_SUBSTATION is parent table and TABLE_ADD_FEEDER is child table. I am able to add data in child table in the foreign key which does not even exist in parent table. There is no error while inserting in foreign key. What is wrong here? Am I missing something. I am new to android studio.
public class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "DATABASE.db";
private static final String TABLE_ADD_SUBSTATION = "ADD_SUBSTATION";
private static final String TABLE_ADD_FEEDER = "ADD_FEEDER";
private static final int DATABASE_VERSION = 3;
public DBHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onConfigure(SQLiteDatabase db) {
db.setForeignKeyConstraintsEnabled(true);
super.onConfigure(db);
}
#Override
public void onCreate(SQLiteDatabase db) {
//table for adding substation
String createAddSubstationTable = "create table " + TABLE_ADD_SUBSTATION
+ "(substationNo INT(5) PRIMARY KEY, substationName VARCHAR(30), type VARCHAR(3), "
+ "serialNo INT(10), dateOfInstallation VARCHAR, totalCapacity INT, circle VARCHAR(10), "
+ "location VARCHAR(20), incomingSubstation int, newFeeder VARCHAR(10), newMeter VARCHAR(10))";
db.execSQL(createAddSubstationTable);
//table for adding feeder
String createAddFeederTable = "create table " + TABLE_ADD_FEEDER
+"(feederNo INT(5) PRIMARY KEY, typeOfConductor VARCHAR(30), conductorCapacity INT(10), incomingLine INT(10), "
+ "outgoingLine INT(10), totalLoad INT(10), totalNoOfConnection INT(10), status INT,"
+ "feederName VARCHAR(30), feederLength INT(10), substationNo INT(5) NOT NULL,"
+ " FOREIGN KEY(substationNo) REFERENCES TABLE_ADD_SUBSTATION(substationNo))";
db.execSQL(createAddFeederTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + TABLE_ADD_SUBSTATION);
db.execSQL("drop table if exists " + TABLE_ADD_FEEDER);
//create table again
onCreate(db);
}
//function to add a substation into database
public char addSubstationIntoDatabase(int substationNo, String substationName, String type, int serialNo,String dateOfInstallation, int totalCapacity, String circle, String location,
int incomingSubstation){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("substationNo", substationNo);
contentValues.put("substationName",substationName);
contentValues.put("type", type);
contentValues.put("serialNo",serialNo);
contentValues.put("dateOfInstallation", dateOfInstallation);
contentValues.put("totalCapacity",totalCapacity);
contentValues.put("circle", circle);
contentValues.put("location", location);
contentValues.put("incomingSubstation", incomingSubstation);
long result = db.insert(TABLE_ADD_SUBSTATION, null, contentValues);
if(result == -1){
Cursor cursor = db.rawQuery("Select substationNo from ADD_SUBSTATION where substationNo = ?", new String[]{String.valueOf(substationNo)});
if(cursor.getCount()>0)
return 'B';
else return 'C';
}
else
return 'D';
}
//function to add feeder into database
public boolean addFeederIntoDatabase(int feederNo,String feederName, int feederLength, String typeOfConductor,
int conductorCapacity, int incomingLine, int outgoingLine, int totalLoad,
int totalNoOfConnection, int status, int substationNo){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("feederNo", feederNo);
contentValues.put("feederName",feederName);
contentValues.put("feederLength", feederLength);
contentValues.put("typeOfConductor", typeOfConductor);
contentValues.put("conductorCapacity", conductorCapacity);
contentValues.put("incomingLine", incomingLine);
contentValues.put("outgoingLine",outgoingLine);
contentValues.put("totalLoad", totalLoad);
contentValues.put("totalNoOfConnection", totalNoOfConnection);
contentValues.put("status", status);
contentValues.put("substationNo", substationNo);
Log.d("contentValues", String.valueOf(contentValues));
long result = db.insert(TABLE_ADD_FEEDER, null, contentValues);
db.close();
if(result == -1)
return false;
else
return true;
}```

In the method onCreate() you construct the string createAddFeederTable by concatenating sql keywords, table names and column names.
But you use TABLE_ADD_SUBSTATION as the name of the table which is referenced by the column substationNo and this is wrong.
TABLE_ADD_SUBSTATION is a variable and not the table's name.
Change your code to this:
String createAddFeederTable = "create table " + TABLE_ADD_FEEDER
+"(feederNo INT(5) PRIMARY KEY, typeOfConductor VARCHAR(30), conductorCapacity INT(10), incomingLine INT(10), "
+ "outgoingLine INT(10), totalLoad INT(10), totalNoOfConnection INT(10), status INT,"
+ "feederName VARCHAR(30), feederLength INT(10), substationNo INT(5) NOT NULL,"
+ "FOREIGN KEY(substationNo) REFERENCES "
+ TABLE_ADD_SUBSTATION
+ "(substationNo))";
db.execSQL(createAddFeederTable);
After this change, uninstall the app from the device to delete the database and rerun to recreate it.
Also, note that the data types INT(10) and VARCHAR do not actually exist in SQLite, although you can use them.
Instead you should use INTEGER and TEXT.

Related

SQLite Table not being created

I have a database created in android studio to save data to . The table is not being created in the database . The error I'm getting is :
03-04 00:55:45.783 25787-25787/com/SQLiteLog: (1) no such table: TableName
03-04 00:55:45.783 25787-25787/com.E/SQLiteDatabase: Error inserting
My code for creating the table is :
#Override
public void onCreate(SQLiteDatabase db) {
db = SQLiteDatabase.openOrCreateDatabase("DB.ad",null);
Log.v(TAG, "*TABLE ");
// create TableName table
db.execSQL(CREATE_TableName_TABLE);
this.checkDataBase();
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
checkDB = SQLiteDatabase.openDatabase(DB_FULL_PATH, null,
SQLiteDatabase.OPEN_READONLY);
checkDB.close();
} catch (SQLiteException e) {
// database doesn't exist yet.
}
return checkDB != null;
}
I was wondering if anyone can tell me why I am getting this error?
String CREATE_TableName_TABLE = "CREATE TABLE TableNames( " +
"Id INT( 30 ) PRIMARY KEY AUTOINCREMENT, " +
"TagNo TEXT, " +
"Description TEXT, " +
"WeeksGone INTEGER( 10 ) NOT NULL DEFAULT 0 );";
Here is an example how to create your database. First your class should extends from SQLiteOpenHelper
Then use super to SQLiteOpenHelper class with your db name and version,
public YourClassName(Context context) {
super(context, "YourDatabaseName", null, 1); // 1 is the version of the database, after each change in your db you should ++.
}
Then create your table:
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
final String SQL_CREATE_BLABLA_TABLE = "CREATE TABLE " + "TableNameHere" + " (" +
"_id" + " INTEGER PRIMARY KEY," +
"name" + " TEXT NOT NULL);";
sqLiteDatabase.execSQL(SQL_CREATE_BLABLA_TABLE);
}
And finally in case you need to upgrade your db version, because you make any change override the onUpgrade method, in order to create again the table.
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + "TableNameHere");
onCreate(sqLiteDatabase);
}
For more information of how to implement SQLite please read this.
Please review the following types in order to create your table:
1.0 Storage Classes and Datatypes
Each value stored in an SQLite database (or manipulated by the database engine) has one of the following storage classes:
NULL. The value is a NULL value.
INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.
REAL. The value is a floating point value, stored as an 8-byte IEEE floating point number.
TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16LE).
BLOB. The value is a blob of data, stored exactly as it was input.
For more information of datatypes please see this link.
So your table should be create like this:
String CREATE_TableName_TABLE = "CREATE TABLE TableNames (Id INTEGER PRIMARY KEY AUTOINCREMENT, TagNo TEXT,
Description TEXT, WeeksGone INTEGER NOT NULL DEFAULT 0 );";

Changed DB, updated DB version can't add data and can't not add data

I am working on an android application that uses two databases. Recently, I had to add a new column to one of the databases. Upon doing so, it broke my database. Installing and re-installing the application on my device did nothing, and I also updated the DB version.
Trying to insert data will net me this error:
E/SQLiteLog﹕ (1) table message_table has no column named msg_type
So, I tried taking out the "msg_type" column from the insert, and inserting data which gave me this error:
E/SQLiteLog﹕ (1299) abort at 8 in [INSERT INTO message_table(recipient,message) VALUES (?,?)]: NOT NULL constraint failed: message_table.msg_typeTEXT
Here is the oncreate:
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
COL_1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " + //msg_id
COL_2 + " TEXT NOT NULL, " + //recipient
COL_3 + " TEXT, " + //message
COL_4 + "TEXT NOT NULL);"); //message type
}
and the insert class:
public boolean addMessage(String recipient, String message, String type){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
//populate message object
contentValues.put(COL_2, recipient);
contentValues.put(COL_3, message);
contentValues.put(COL_4, type);
//insert new message
long result = db.insert(TABLE_NAME, null, contentValues);
//check if operation was successful
if(result == -1)
return false;
else
return true;
}
How can I be getting an error for either case? I thought that it didn't recognize the new column was added from the first error, but it also doesn't like not receiving the data for that column.
The error is happening because there is no space between the column name and the TEXT. So the column name becomes message_table.msg_typeTEXT:
COL_4 + "TEXT NOT NULL);"); //message type
This should fix the error:
COL_4 + " TEXT NOT NULL);"); //message type

"no such column: id (code 1): , while compiling: SELECT id ..."

Here is my code:
DataBaseAlarm mDbHelper = new DataBaseAlarm(this);
db = mDbHelper.getWritableDatabase();
private static final String SQL_CREATE_ENTRIES="CREATE TABLE IF NOT EXISTS"+TABLE_NAME+" ("+rowid+" INTEGER PRIMARY KEY AUTOINCREMENT, "+Title+TEXT_TYPE+Time+TEXT_TYPE+Date+TEXT_TYPE+Repeat+TEXT_TYPE+Note+" TEXT NOT NULL);";
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
Cursor c = db.query(
"Alarms", // The table to query
cols, // The columns to return
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
);
from=new String[]{"title","note","time","date","repeat","_id"};
to=new int[]{R.id.title_row,R.id.note_row,R.id.time_row,R.id.date_row,R.id.repeat_row};
adapterCursor =new SimpleCursorAdapter(MainActivity.this, R.layout.alarm_row, c, from, to);
l_list.setAdapter(adapterCursor);
ContentValues cv = new ContentValues();
cv.put("title",msg);
cv.put("note",note);
cv.put("time",hour+":"+minute);
cv.put("date",month+"/"+day+"/"+year);
cv.put("Repeat","daily");
db.insert("Alarms",null,cv);
and for some reason I'm getting this error:
Caused by: android.database.sqlite.SQLiteException: no such column: id (code 1): , while compiling: SELECT id, title, time, date, repeat, note FROM Alarms
Take a look at your table creation code:
private static final String SQL_CREATE_ENTRIES="CREATE TABLE IF NOT EXISTS"+TABLE_NAME+" ("+rowid+" INTEGER PRIMARY KEY AUTOINCREMENT, "+Title+TEXT_TYPE+Time+TEXT_TYPE+Date+TEXT_TYPE+Repeat+TEXT_TYPE+Note+" TEXT NOT NULL);";
It's a mess, and it's full of errors.
It should be something like:
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME +
" (" + rowid + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
Title + " TEXT, " + Time + " TEXT, " + Date + " TEXT, " +
Repeat + " TEXT, " + Note + " TEXT NOT NULL)";
[EDIT]
Also, this
cv.put("date",month+"/"+day+"/"+year);
is not a valid timeString
This one (assuming that year is a 4 character string and month and day are 2 character strings) is:
cv.put("date", year + "-" + month + "-" + day);
For your reference: http://www.sqlite.org/lang_datefunc.html

Stuck with database Insertion

I'm developing an android application where I'm Inserting values from the Server into the local database. Everytime I insert I'll check whether the same row already exists or not using some value. If already exists means I'll do the update .otherwise, Insertion.
Like the following
if(checkValueAlreadyInDb("SELECT * FROM User WHERE UserID='"+fieldValues
.getProperty("UserID").toString()+"'"))
{
updateDb("User", contentValues," UserID='"+fieldValues
.getProperty("UserID").toString()+"'" );
}
else
{
insertIntoDb("User", contentValues);
}
updateDb() function
public void updateDb(String TableName, ContentValues contentValues,
String whereClause) {
SQLiteDatabase sqLiteDatabase = db.getWritableDatabase();
sqLiteDatabase.update(TableName, contentValues, whereClause, null);
Log.e("Value",db.getReadableDatabase().rawQuery("SELECT * FROM User WHERE"+whereClause, null).getString(2));
sqLiteDatabase.close();
}
insertIntoDb() function
public void insertIntoDb(String TableName, ContentValues contentValues) {
SQLiteDatabase sqLiteDatabase = db.getWritableDatabase();
sqLiteDatabase.insert(TableName, null, contentValues);
sqLiteDatabase.close();
}
In my Database the table User is created like below,
DATABASE_TABLES.add("CREATE TABLE User("
+"UserID INTEGER NOT NULL ,"
+"UserName varchar(50) NULL,"
+"Password varchar(50) NULL,"
+"FirstName varchar(50) NULL ,"
+"LastName varchar(50) NULL,"
+"CompanyName varchar(50) NULL,"
+"MobilePhone LONG NULL,"
+"EmailAddress varchar(50) NULL,"
+"Active BOOLEAN NULL,"
+"ClientID INTEGER NULL,"
+"RoleID INTEGER NULL,"
+"ProjectID INTEGER NULL,"
+"ProductID INTEGER NULL,"
+"CreatedBy varchar(50) NULL,"
+"UpdatedBy varchar(50) NULL ,"
+"Createdtime DATE NULL ,"
+"UpdatedTime DATE NULL,"
+"IsDeleted BOOLEAN NULL)");
My problem is after inserting or updating the values , the cursor count of User table is zero
if I create cursor like below
database.getReadableDatabase.rawQuery("SELECT * FROM User where UserName='Rakesh' and Password='123' and Active='true'",null).getString(0);
and throws the exception
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 126
I can't realize where the mistake is happened . please give me a solution .
try this way:
Cursor mCursor = database.getReadableDatabase.rawQuery("SELECT * FROM User where UserName='Rakesh' and Password='123' and Active='true'",null);
if(mCursor.getCount()>0 && mCursor.moveToFirst()){
do{
Log.d("data: ",mCursor.getString(0));
}while(mCursor.moveToNext(););
}
And make sure that you have inserted data into your Table.
Sqlite does not support 'varchar' data type so make it text.Sql datatypes
And like others pointed,do check whether your return result, that is the cursor ,has results in it with getCount() function.To do that take result of your query into a Cursor object.Later extract the string from the cursor.You are supplying column 0 to the getString() function which is wrong.

E/SQLiteLog: (1) table keyTable has no column named number

I keep getting this error:
"table keyTable has no column named number"
Still pretty new to Android, so no clue why this happens, can anyone spot the error?
This is my Database class:
public class KeyDatabase extends SQLiteOpenHelper {
private static final String database_name = "KeyDatabase.db";
private static final int database_version = 1;
KeyDatabase (Context context){
super(context,database_name,null,database_version);
}
#Override
public void onCreate (SQLiteDatabase db){
db.execSQL("CREATE TABLE " + KeyTableClass.table_name
+ "(" + KeyTableClass.id + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KeyTableClass.number + " TEXT, "
+ KeyTableClass.key + " TEXT);");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS " + KeyTableClass.table_name);
onCreate(db);
}
public long InsertKey (String number, String key){
ContentValues valuesToInsert = new ContentValues();
valuesToInsert.put(KeyTableClass.number, number);
valuesToInsert.put(KeyTableClass.key, key);
SQLiteDatabase sd = getWritableDatabase();
long result = sd.insert(KeyTableClass.table_name, KeyTableClass.number, valuesToInsert);
return result;
}
This is my class for my table:
public class KeyTableClass {
//The name of the table
public static final String table_name = "keyTable";
//The columns of the table
public static String id = "id";
public static String number = "number";
public static String key = "key";
}
Maybe you've edited the DB onCreate but didn't let it re-run?
Try uninstalling/install the App, Or update database_version to =2.
You don't fit the requirements for the insertion :
public long insert (String table, String nullColumnHack, ContentValues values)
Added in API level 1 Convenience method for inserting a row into the
database.
Parameters table the table to insert the row into
nullColumnHack optional; may be null. SQL doesn't allow inserting a
completely empty row without naming at least one column name. If your
provided values is empty, no column names are known and an empty row
can't be inserted. If not set to null, the nullColumnHack parameter
provides the name of nullable column name to explicitly insert a NULL
into in the case where your values is empty. values this map contains
the initial column values for the row. The keys should be the column
names and the values the column values Returns the row ID of the newly
inserted row, or -1 if an error occurred
Could you try to do :
sb.insert(table_name, null, valuesToInsert);

Categories

Resources