I am writing an Android app and need a database for it. I will have three tables but only managed to make one right now. I do them in the console to debug and to implement them in my Javacode later. The following statements were succesfull:
sqlite3 progressapp.db
CREATE TABLE Z_Type(_Z_T_ID INTEGER PRIMARY KEY NOT NULL,
Description TEXT NOT NULL, Unit TEXT NOT NULL);
But now I want to refference the PK of T_Type in my other table:
CREATE TABLE goals (_Z_id INTEGER PRIMARY KEY NOT NULL, Title TEXT NOT NULL,
Type INTEGER NOT NULL, FOREIGN KEY(Type) REFERENCES Z_Type(_Z_T_ID),
Timeframe TEXT, Goaldate INTEGER);
Is Type INTEGER NOT NULL, FOREIGN KEY(Type) REFERENCES Z_Type(_Z_T_ID) a valid SQLite Statement in Android? It says "Error: near "Timeframe": syntax error" But I simply can't find it due to lack with SQL Experience I guess.
Is there a better way to reference the FK maybe?
Try this:
CREATE TABLE goals (_Z_id INTEGER PRIMARY KEY NOT NULL, Title TEXT NOT NULL,
Type INTEGER NOT NULL,Timeframe TEXT, Goaldate INTEGER, FOREIGN KEY(Type) REFERENCES Z_Type(_Z_T_ID));
I think that the order is important.
For further documentation you could visit sqlite.org/foreignkeys.html
You can define the reference as part of the column definition
CREATE TABLE goals (_Z_id INTEGER PRIMARY KEY NOT NULL, Title TEXT NOT NULL,
Type INTEGER NOT NULL REFERENCES Z_Type(_Z_T_ID),
Timeframe TEXT, Goaldate INTEGER);
In a sqlite CREATE TABLE statement, column definitions come first and table constraints only after that.
FOREIGN KEY(Type) REFERENCES Z_Type(_Z_T_ID) is a table constraint that should go at the end.
Related
In my android project's SqLite database I have to create a foreign key which is the primery key of the table. I wrote the sql statement as below using SQLiteManager.
CREATE TABLE OBTTourVehicleUpdate
(
TourHeaderCode INT PRIMARY KEY NOT NULL,
TourVehicleProcessCode INT NOT NULL,
VehicleCode CHAR(10),
TourStart TEXT ,
TourEnd TEXT ,
LastMilage DOUBLE,
NewMilage DOUBLE,
CONSTRAINT FOREIGN KEY (TourHeaderCode) REFERENCES OBTTourHeader(TourHeaderCode)
);
It gives me an error message saying that
Internal Error. near FOREIGN: syntax error.
The table structure of two tables are as below.
how can I fix this.
Remove CONSTRAINT from your code. Just do the
FOREIGN KEY (TourHeaderCode) REFERENCES OBTTourHeader(TourHeaderCode).
Remember to call the table on the onCreate() and onUpdate() and also update the DB_version. And to be on the safe side, do not declare your FK as the PK too.
You get that error because your syntax is indeed incorrect.
Read the official SQLite documentation to learn more about how it should be used.
CREATE TABLE OBTTourVehicleUpdate
(
TourHeaderCode INT PRIMARY KEY NOT NULL,
TourVehicleProcessCode INT NOT NULL,
VehicleCode CHAR(10),
TourStart TEXT ,
TourEnd TEXT ,
LastMilage DOUBLE,
NewMilage DOUBLE,
FOREIGN KEY(TourHeaderCode) REFERENCES OBTTourHeader(TourHeaderCode)
);
Something like that should work.
CREATE TABLE OBTTourVehicleUpdate
(
TourHeaderCode INT PRIMARY KEY NOT NULL,
TourVehicleProcessCode INT NOT NULL,
VehicleCode CHAR(10),
TourStart TEXT ,
TourEnd TEXT ,
LastMilage DOUBLE,
NewMilage DOUBLE,
FOREIGN KEY(TourHeaderCode) REFERENCES OBTTourHeader(TourHeaderCode)
);
You don't need to use CONSTRAINT in your query. Follow this article about Foreign Key Constraints
I'm trying to create a table and I've tried so many times to figure this out... for some reason it won't accept this.. it's saying something about the auto_increment
create table if not exists Assignments(
id auto_increment primary key,
class_name VARCHAR(30),
assignment_name VARCHAR(30) not null,
due_date VARCHAR(30) not null,
notes VARCHAR(30));
whats the problem?
EDIT: i am trying to use SQLite eventually but this command was written on my mySQL thru WAMP
First of all, Android uses SQLite, so your mysql tag is slightly incorrect unless I'm missing something you're doing.
Secondly, you would say
CREATE TABLE ASSIGNMENTS(id INTEGER PRIMARY KEY, class_name TEXT, assignment_name TEXT NOT NULL, due_date TEXT NOT NULL, notes TEXT);
"autoincrement" is handled automatically if you set your primary key as an INTEGER type, even though under the covers SQLite uses strings for everything
reference: SQLite datatypes
further reference: INTEGER PRIMARY KEY
Even more reference: "If an INSERT statement attempts to insert a NULL value into a rowid or integer primary key column, the system chooses an integer value to use as the rowid automatically. A detailed description of how this is done is provided separately."
It is autoincrement, not auto_increment
I am new on android. I am trying to create a table in a db using the following code but there is some error
db.beginTransaction();
try {
db.execSQL("CREATE TABLE IF NOT EXISTS `book` (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(100) NOT NULL,`author_name` varchar(100) NOT NULL,`text_b` text NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;");
db.setTransactionSuccessful();
} catch (SQLiteException e) {
Log.d("Maaz", "Exception 2 : SQL Exception 2 " + e.getMessage());
} finally {
db.endTransaction();
}
The above code is giving me the following error
Failure 1 (near "AUTO_INCREMENT": syntax error)
on 0x23c510 when preparing 'CREATE TABLE IF NOT EXISTS `book` (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(100) NOT NULL,`author_name` varchar(100) NOT NULL,`text_b` text NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;'.
Kindly help me. Thanks in advance.
Change AUTO_INCREMENT to AUTOINCREMENT.
Edit:
Try this,
CREATE TABLE IF NOT EXISTS book (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
title varchar(100) NOT NULL,
author_name varchar(100) NOT NULL,
text_b TEXT NOT NULL
);
This Worked at last in my case.
Answer :
CREATE TABLE IF NOT EXISTS book (
_id Integer PRIMARY KEY AUTOINCREMENT,
title varchar(100) NOT NULL,
author_name varchar(100) NOT NULL,
text_b TEXT NOT NULL);
Removing Engine, DEFAULT CHARSET worked for me
what kind of database, it makes a difference for the SQL syntax. You should try to create the database table first in the console editor and then you can paste that syntax in your code. It's also usually not a good idea to create tables from code with a generic execSQL. You should use an ORM or database library or framework for this. A continuous integration server could also create this table unless your are creating it on the client's android device. Hibernate is nice for keeping messy SQL out of your code.
Can you tell us what kind of database?
You can also check out this article:
http://androidforbeginners.blogspot.com/2010/01/creating-multiple-sqlite-database.html
Very close syntax if you are using SQLite
It seems you have quotes surrounding the identifiers (I.e. books). Remove them.
Now I have a weird problem, I've done all kinds of test and I believe I'm seeing something weird.
I create three tables in SQLiteOpenHelper:
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(TABLE_CHANNELS_CREATE);
db.execSQL(TABLE_FEEDS_CREATE);
db.execSQL(TABLE_FEEDMAP_CREATE);
}
catch (SQLiteException e){
Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
The CREATE statements for the three tables follow:
CREATE TABLE IF NOT EXISTS IRChannels (
ChannelId INTEGER PRIMARY KEY,
ChannelHash TEXT NOT NULL,
ChannelTitle TEXT NOT NULL,
ChannelDesc TEXT, ChannelLink TEXT);
CREATE TABLE IF NOT EXISTS IRFeeds (
FeedId INTEGER PRIMARY KEY,
FeedHash TEXT NOT NULL,
FeedTitle TEXT NOT NULL,
FeedDescription TEXT,
FeedLink TEXT);
CREATE TABLE IF NOT EXISTS IRFeedMap (
ChannelHash_FK TEXT NOT NULL,
FeedHash_FK TEXT NOT NULL,
FOREIGN KEY (ChannelHash_FK) REFERENCES IRChannels (ChannelHash),
FOREIGN KEY (FeedHash_FK) REFERENCES IRFeeds (FeedHash));
The problem is apparently the column FeedHash in IRFeeds is not created while others are. I'm looking at the output in sqlite3 command prompt;
sqlite> .schema
CREATE TABLE IRChannels (
ChannelId INTEGER PRIMARY KEY,
ChannelHash TEXT NOT NULL,
ChannelTitle TEXT NOT NULL,
ChannelDesc TEXT,
ChannelLink TEXT);
CREATE TABLE IRFeedMap (
ChannelHash_FK TEXT NOT NULL,
FeedHash_FK TEXT NOT NULL,
FOREIGN KEY (ChannelHash_FK) REFERENCES IRChannels (ChannelHash),
FOREIGN KEY (FeedHash_FK) REFERENCES IRFeeds (FeedHash));
CREATE TABLE IRFeeds (
FeedId INTEGER PRIMARY KEY,
FeedHash TEXT NOT NULL,
FeedTitle TEXT NOT NULL,
FeedDescription TEXT,
FeedLink TEXT);
This does list the FeedHash column in IRFeeds. However, when I execute
sqlite> select * from IRFeeds where FeedHash='';
SQL error: no such column: FeedHash
All other columns do not give such errors. This condition is causing my code to fail unexpectedly as well. What could I be missing?
sqlite> select * from IRFeeds where FeedID=1;
sqlite> select * from IRFeeds where FeedTitle='';
sqlite> select * from IRFeeds where FeedDescription='';
sqlite> select * from IRFeeds where FeedLink='';
No errors above when I execute select statement for other columns.
There is no error in your SQL. I tested and everything was created properly. Also your SQL query did not cause no such column error. So try to delete the database with context.deleteDatabase(databaseName); and try again.
After an entire day of struggle, I managed to isolate why the problem triggers. Still don't know why, but it does fix the problem. The problems occurs because of the following table which has foreign keys on the other two tables:
CREATE TABLE IRFeedMap (
ChannelHash_FK TEXT NOT NULL,
FeedHash_FK TEXT NOT NULL,
FOREIGN KEY (ChannelHash_FK) REFERENCES IRChannels (ChannelHash),
FOREIGN KEY (FeedHash_FK) REFERENCES IRFeeds (FeedHash));
Changing the column names of foreign key columns to be the same as the column they reference fixes the problem. I changed the statement above to:
CREATE TABLE IRFeedMap (
ChannelHash TEXT NOT NULL,
FeedHash TEXT NOT NULL,
FOREIGN KEY (ChannelHash) REFERENCES IRChannels (ChannelHash),
FOREIGN KEY (FeedHash) REFERENCES IRFeeds (FeedHash));
And voila! Sanity was restored. Beats me.
In my case I was using a SQLite reserved word (column, that was)
I ended up in this SO question, so maybe it helps others in my situation
I have a table with a composite primary key and I am having trouble inserting. The code used to create the table is:
CREATE TABLE ClassEvent (
EventName varchar(10) NOT NULL,
CourseId varchar(10) NOT NULL,
EventType varchar(20),
EventWeight number(3),
DueDate DATE NOT NULL,
FOREIGN KEY (CourseId) REFERENCES Courses(CourseId),
PRIMARY KEY (CourseId, EventName));
The problem I am having is when I want to insert records that have values that may not be unique for the columns CourseId or EventName, but are a unique combination of the 2.
for example, if I try to run the following 2 inserts:
INSERT INTO ClassEvent VALUES('Assignment 1','60-415','Assignment',10,'12/10/2010');
INSERT INTO ClassEvent VALUES('Project 1','60-415','Project',15,'5/12/2010');
I get the following error:
Error: columns CourseId, EventName are not unique.
and the second insert does not make it into the DB. Why does this error out? I thought that a composite primary key requires that the combination of both values are unique. In my above inserts, the values for the EventName column are different even though the values for CourseId are the same. Shouldn't this be seen as 2 unique combinations and thus 2 different primary keys?
My table needs to be able to hold several different events for each CourseId, but each Event must be unique for each Course. I need to be able to insert values into the table like:
EventName CourseId
Assignment 1 60-415
Project 1 60-415
Assignment2 60-415
Project 2 60-415
Assignment 1 60-367
Project 1 60-367
and so on. Can anyone tell me how I can get this to work? Why are these composite PK's not being seen as unique entries? Any help would be much appreciated.
Here is the java function I am using for the insert:
public void addNewClassEvent(ContentValues values) {
SQLiteDatabase db = openConnection();
db.insert("ClassEvent", null, values);
db.close();
}
Could this be causing the problem?
You can have a composite primary key in SQLite, but you
have to create the key when you create the table:
CREATE TABLE example1(
field1 FLOAT,
field2 TEXT,
PRIMARY KEY(field1, field2)
);
You cannot create the primary key after the fact using ALTER TABLE.
On the other hand, you can create a UNIQUE INDEX after the fact
which has essentially the same effect as a PRIMARY KEY:
CREATE UNIQUE INDEX pk_index ON "table1"("field1","field2");
I am not sure how you have created, the tables, and if you have added the primary index later, but grab the database to your desktop, and check out how works in a desktop environment.
You can't make combinations like that, but you don't need them. What is stopping you from just having a truly id column ?