I'm trying to push a database to the emulator. I created the database with a script on my desktop computer, it looks the same as the database created by my SQLiteOpenHelper subclass:
CREATE TABLE android_metadata (locale TEXT);
insert into android_metadata values('en_US');
CREATE TABLE notes (_id integer primary key autoincrement,
key text,
content text not null,
modifydate text,
createdate text,
syncnum integer,
version integer,
minversion integer,
sharekey text,
publishkey text,
deleted integer not null default 0,
pinned integer not null default 0,
unread integer not null default 0);
CREATE TABLE tags (_id integer primary key autoincrement,
name text not null,
pos integer not null,
noteid integer not null,
foreign key(noteid) references notes (_id));
But for some reason the app tries to recreate the database even though it already exists. It fails when it tries to create a table that already exists in the database. Maybe someone here knows why?
OK. It turns out that I need to set the version on the database to the same version that my code expects. This is done in my sqlite script like so:
PRAGMA user_version = 1;
Related
I'm confused about the correct usage and implementation of the "Foreign KEY" in the SQLite Database in Android.
I created a DB with several relations, as following:
CREATE TABLE "food" (
`_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`name` TEXT NOT NULL,
`description` TEXT,
`category_id` INTEGER,
FOREIGN KEY(`category_id`) REFERENCES food(_id) )
CREATE TABLE `category` (
`_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`cagory_name` TEXT NOT NULL)
CREATE TABLE "favourites" (
`_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`id_favourite` INTEGER NOT NULL,
FOREIGN KEY(`id_favourite`) REFERENCES food ( _id ))
As you can see, there are 3 tables and the _id of "food" is the foreign key connecting the table "category" and "favourites".
Now, in Android I don't see happening ANYTHING that proves that I created such a relation among tables. Do I miss some declaration to make it effective?
How does it work in Android?
The category_id foreign key reference seems odd.
Is there a reason it's:
FOREIGN KEY(`category_id`) REFERENCES food(_id)
and not
FOREIGN KEY(`category_id`) REFERENCES category(_id)
To make sure foreign key constraints are enforced, in SQLite run
PRAGMA foreign_keys = ON;
See http://www.sqlite.org/foreignkeys.html for documentation.
I created a table called DRINK. I inserted two rows in to it initially. When upgraded, I would like to delete both rows and reset my Primary Key to 1. I am getting the rows to delete but am not having any luck resetting the primary key. Does anybody know the syntax on how to do that or if it's even possible? Here's the function which is called from my onUpdate function:
private void updateMyDatabase(SQLiteDatabase db, int olderVersion, int newVersion){
Log.v("DatabaseHelper","UPDATE MY DATABASE");
if (olderVersion<1){
db.execSQL("CREATE TABLE DRINK (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "NAME TEXT, "
+ "DESCRIPTION TEXT, "
+ "IMAGE_RESOURCE_ID INTEGER);");
insertDrink(db,"latte","Espresso and Steamed Milk",R.drawable.latte);
insertDrink(db, "cappuccino", "This a Cappuccino", R.drawable.cap);
}
if (olderVersion < 2){
db.execSQL("delete from DRINK");
db.execSQL("alter table AUTO_INCREMENT =1"); //*** NEED HELP HERE***
insertDrink(db, "coff", "Espresso and Steamed Milk", R.drawable.latte);
}
}
I found this piece of code online but it's not working. Thank you.
db.execSQL("alter table AUTO_INCREMENT =1");
Deleteing the rows won't reset ROWID.
SQLite documentation states:
SQLite keeps track of the largest ROWID that a table has ever held
using the special SQLITE_SEQUENCE table. The SQLITE_SEQUENCE table is
created and initialized automatically whenever a normal table that
contains an AUTOINCREMENT column is created. The content of the
SQLITE_SEQUENCE table can be modified using ordinary UPDATE, INSERT,
and DELETE statements. But making modifications to this table will
likely perturb the AUTOINCREMENT key generation algorithm.
This sql should do what you need:
UPDATE SQLITE_SEQUENCE SET seq = <n> WHERE name = <table>
Where n is the sequence you wish to set and table is your table name
I am using SQLite to work on an android application. What I have learned so far is that a table made in SQLite requires a column called _id. So, for instance, to create a table, I use the following SQL Statement:
CREATE TABLE IF NOT EXISTS Semesters(
_id INTEGER PRIMARY KEY AUTOINCREMENT,
semester_name TEXT,
is_current TEXT
GPA REAL);
However, now if I want to create a seperate table in the same database, what would I name the primary key column? For instance, this is the table I want to create:
CREATE TABLE IF NOT EXISTS Classes(
_id INTEGER PRIMARY KEY AUTOINCREMENT,
course_name TEXT);
Now, both the semesters table and the courses table have a column called _id, and if I want to make a foreign key reference to the _id column in the semesters table, I will have to call it by the table name. Is there any way to make this simpler by using different names for ids?
Thanks.
For example, you make a third table and want to use both primary keys from your tables as foreign keys:
CREATE TABLE ClassSemester(
_id INTEGER PRIMARY KEY AUTOINCREMENT,
semester_id INTEGER,
class_id INTEGER,
FOREIGN KEY(semester_id) REFERENCES Semesters(_id),
FOREIGN KEY(class_id) REFERENCES Classes(_id)
);
More details in here:
http://www.sqlite.org/foreignkeys.html
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
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