How to use multiple foreign keys in one table in sqlite? - java

String Post_Code = "CREATE TABLE IF NOT EXISTS PostCode("
+ "PostCode_ID integer PRIMARY KEY, "
+ "Code string NOT NULL, "
+ "City_ID integer,"
+ "FOREIGN KEY (City_ID)"
+ "REFERENCES City (City_ID)"
+ "ON UPDATE CASCADE "
+ "ON DELETE SET NULL, "
+ "County_ID integer,"
+ "FOREIGN KEY (County_ID)"
+ "REFERENCES County (County_ID)"
+ "ON UPDATE CASCADE "
+ "ON DELETE SET NULL"
+ ");";
I believe it's most likely to be something within the first foreign key reference.

Either move all the FOREIGN KEY definitions at the end of the statement:
CREATE TABLE IF NOT EXISTS PostCode(
PostCode_ID integer PRIMARY KEY,
Code TEXT NOT NULL,
City_ID integer,
County_ID integer,
FOREIGN KEY (City_ID) REFERENCES City (City_ID) ON UPDATE CASCADE ON DELETE SET NULL,
FOREIGN KEY (County_ID)REFERENCES County (County_ID) ON UPDATE CASCADE ON DELETE SET NULL
);
or, define each foreign key right after the definition of each column without the FOREIGN KEY keywords:
CREATE TABLE IF NOT EXISTS PostCode(
PostCode_ID integer PRIMARY KEY,
Code TEXT NOT NULL,
City_ID integer REFERENCES City (City_ID) ON UPDATE CASCADE ON DELETE SET NULL,
County_ID integer REFERENCES County (County_ID) ON UPDATE CASCADE ON DELETE SET NULL
);
See the demo.
Note that there is no string data type in SQLite.
I changed it to TEXT.

Related

"Missing columns in relationship" when creating table

I have tried to create three tables(CUSTOMERS, VEHICLES and RENTALS), the third table (RENTALS) has foreign keys referring to the two primary keys of the first two tables (CUSTOMERS and RENTALS). When creating this third table I get an error Missing columns in relationship(Rel=CUSTOMERS[[]] -> RENTALS[[]])
Here's my codes
private void createTables() throws SQLException {
Statement statement = conn.createStatement();
statement.executeUpdate("CREATE TABLE CUSTOMERS(custNumber AUTOINCREMENT PRIMARY KEY, " +
"firstName VARCHAR(155) NOT NULL, surname VARCHAR(155) NOT NULL, idNum INTEGER NOT NULL, phoneNum INTEGER NOT NULL, canRent BIT NOT NULL)");
statement.executeUpdate("CREATE TABLE VEHICLES(vehNumber AUTOINCREMENT PRIMARY KEY, make VARCHAR(155) NOT NULL, " +
"category VARCHAR(155) NOT NULL, rentalPrice FLOAT NOT NULL, availableForRent BIT NOT NULL)");
statement.executeUpdate("CREATE TABLE RENTALS(rentalNumber AUTOINCREMENT PRIMARY KEY, dateRental VARCHAR(155) NOT NULL, dateReturned VARCHAR(155) NOT NULL, " +
"pricePerDay FLOAT NOT NULL, totalRental FLOAT NOT NULL, custNumber INTEGER FOREIGN KEY REFERENCES CUSTOMERS(custNumber), " +
"vehNumber INTEGER FOREIGN KEY REFERENCES VEHICLES(vehNumber))");
System.out.println("Database populated");
}
and here's the error
Your help will be very much appreciated, I have looked around but found nothing that helps.
In Access, an AutoNumber field (DDL: AUTOINCREMENT or COUNTER) is a "Long Integer".
In UCanAccess DDL, INTEGER creates an "Integer" (16-bit) field and LONG creates a "Long Integer" (32-bit) field.
You need to declare your foreign key columns as LONG, not INTEGER.

Why is sqlite auto_increment not incrementing?

I've got a database set up to store notes. I want to auto increment the first column. I've tried this, but when I read from the database every result in that column is 'null'.This is the code for creating the DB.
private static final String NOTES_TABLE_CREATE =
"CREATE TABLE " + NOTES_TABLE_NAME + " (" +
COLUMN_NAMES[0] + " INTEGER AUTO_INCREMENT, " +
COLUMN_NAMES[1] + " TEXT, " +
COLUMN_NAMES[2] + " TEXT, " +
COLUMN_NAMES[3] + " TEXT, " +
COLUMN_NAMES[4] + " TEXT, " +
COLUMN_NAMES[5] + " TEXT, " +
COLUMN_NAMES[6] + " TEXT);";
This is the code for getting the DB result.
SQLiteDatabase db = this.getReadableDatabase();
Cursor result = db.query(NOTES_TABLE_NAME, COLUMN_NAMES, null, null, null, null, null, null);
result.moveToFirst();
result.moveToNext();
System.out.println(result.getInt(0));
System.out.println(result.getString(1));
This is the output from logcat
04-09 17:56:17.981 22147-22147/com.example.a8460p.locationotes I/System.out: 0
04-09 17:56:17.981 22147-22147/com.example.a8460p.locationotes I/System.out: notetitle1234567890
AUTO_INCREMENT (as opposed to INTEGER PRIMARY KEY AUTOINCREMENT) is not supported in sqlite.
This is a little non-obvious, because sqlite silently ignores column constraints it does not recognize:
sqlite> CREATE TABLE test (
a INTEGER FABBELBABBEL NOT NULL
);
sqlite> .schema test
CREATE TABLE test (a INTEGER FABBELBABBEL NOT NULL);
sqlite> INSERT INTO test (a) VALUES (1);
sqlite> INSERT INTO test (a) VALUES (NULL);
Error: NOT NULL constraint failed: test.a
AUTOINCREMENT on the other hand, is supported for integer primary keys and only there, so the obvious workaround attempt is not supported, either:
sqlite> CREATE TABLE test (a INTEGER AUTOINCREMENT NOT NULL, b INTEGER);
Error: near "AUTOINCREMENT": syntax error
In short: Auto increment is only available for integer primary keys.

Syntax error creating a foreign key

I am trying to create the following tables design but I am getting this error below how can I set the foreign key for the stops table in the arrivaltimes table?
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOREIGN KEY REFERENCES stops(stop_id) )' at line 4
stt.execute("CREATE TABLE IF NOT EXISTS stops"
+ "(stop_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, "
+ " name varchar(30) NOT NULL, " + " route INT(11) NOT NULL, "
+ " lat double(10,6) NOT NULL, "
+ " longi double(10,6)NOT NULL) ");
stt.execute("CREATE TABLE IF NOT EXISTS arrivaltimes(id INT(11) NOT NULL PRIMARY KEY,"
+ " weekday VARCHAR(20) NOT NULL,"
+ "arrivaltime time NOT NULL,"
+ " stop_id INT FOREIGN KEY REFERENCES stops(stop_id) )" );
Change
stop_id INT FOREIGN KEY REFERENCES stops(stop_id)
to
stop_id INT, FOREIGN KEY fk_stop_id(stop_id) REFERENCES stops(stop_id)
I have updated the query, please take note of the syntax of the FOREIGN KEY, where you had an error. Cheers!
stt.execute("CREATE TABLE IF NOT EXISTS stops"
+ "(stop_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, "
+ " name varchar(30) NOT NULL, " + " route INT(11) NOT NULL, "
+ " lat double(10,6) NOT NULL, "
+ " longi double(10,6)NOT NULL) ");
stt.execute("CREATE TABLE IF NOT EXISTS arrivaltimes(id INT(11) NOT NULL PRIMARY KEY,"
+ " weekday VARCHAR(20) NOT NULL,"
+ "arrivaltime time NOT NULL,"
+ " FOREIGN KEY (stop_id) REFERENCES stops(stop_id) )" );
If you look at the MySQL CREATE TABLE syntax, then you have the choice between:
An inline definition (note the absence of FOREIGN KEY)
stop_id INT REFERENCES stops(stop_id)
and an explicit definition:
stop_id INT,
FOREIGN KEY (stop_id) REFERENCES stops(stop_id)
or better (with named constraint):
stop_id INT,
CONSTRAINT fk_arrivaltimes_stops FOREIGN KEY (stop_id) REFERENCES stops(stop_id)

How to Insert a value where not exist in SQLite Android

I want to insert values into my table only when values don't exist in the table.
String CREATETABLE = "CREATE TABLE contacts ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, "+
"phone TEXT )";
Here is my code to create the table, I used UNIQUE(phone), and it doesn't work.
And to add a new contact I am using this code:
ContentValues values = new ContentValues();
values.put("name", contact.getName()); // get title
values.put("phone", contact.getNumero()); // get author
// 3. insert
db.insert("contacts", // table
null, //nullColumnHack
values);
I don't think there is a way of doing that without retrieving the row first. You query the database looking for that particular contact (which you have to specify at least one column to be unique, or any combination of columns to be primary key) otherwise how would you handle two person with the same name?.
So you query and search for the desired person, if you find it, check if the column is null and a) insert if it is, b) ignore if it isn't. If the query doesn't find any person, you cant just insert.
About the unique constraint, its like this:
String CREATETABLE = "CREATE TABLE contacts ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"phone TEXT UNIQUE)";
In your sample you are using SQLiteDatabase.insert(), try to use SQLiteDatabase.insertWithOnConflict() with one of values CONFLICT_IGNORE, CONFLICT_REPLACE or others.
Also have a look about implementing database as ContentProvider which is much harder to understand but really good to know.

Android Sqlite and foreign keys failing

I'm testing the foreign keys in Android and I have problems I don't understand:
To create the tables (with hard-coded values)
db.execSQL("CREATE TABLE IF NOT EXISTS table_A ( " +
"_id long primary key , value1 long );");
db.execSQL("CREATE TABLE IF NOT EXISTS table_B ( " +
"_id long primary key , value1fk long , value2 long,"+
"FOREIGN KEY (value1fk) REFERENCES table_A (value1) ON DELETE CASCADE);");
then I execute:
ContentValues values = new ContentValues();
values.put("_id", 1);
values.put("value1", 200);
long result = mDb.insert("table_A", null, values);
Log.e("","done (" + result + ")");
values = new ContentValues();
values.put("_id", 1);
values.put("value1fk", 200);
values.put("value2", 10);
result= mDb.insert("table_B", null, values);
Log.e("","done (" + result + ")");
The output is
done(1)
done(-1)
Giving the second insert an foreign key mismatch
E/SQLiteDatabase(25476): Error inserting _id=1 value1fk=200 value2=10
E/SQLiteDatabase(25476): android.database.sqlite.SQLiteException: foreign key mismatch: , while compiling: INSERT INTO table_B(_id,value1fk,value2) VALUES (?,?,?)
Why is that happening?
According to sqlite documentation on foreign keys
http://www.sqlite.org/foreignkeys.html
you need to either :
use the primary key as your foreign key
FOREIGN KEY (value1fk) REFERENCES table_A (_id)
use a Unique column as a foreign key
CREATE TABLE IF NOT EXISTS table_A (_id long primary key , value1 long UNIQUE);
The value_1 field in table_A is not the primary key. Shouldn't it be
FOREIGN KEY (value1fk) REFERENCES table_A (_id)...
instead?

Categories