Android: mySQL, create table command - android

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

Related

Is there any way to make Room generate an autogenerating primary key without AUTOINCREMENT?

My Room database has the following entity:
#Entity
public class SmsMessage {
#PrimaryKey
public long id;
public boolean incoming;
public String sender;
public String receiver;
public String body;
public long timestamp;
}
This fails with the following RuntimeException when trying to insert more than one item into the database:
SQLiteConstraintException: PRIMARY KEY must be unique (code 19)
The generated SQL CREATE TABLE statement looks like this:
CREATE TABLE `SmsMessage` (
`id` INTEGER NOT NULL,
`incoming` INTEGER NOT NULL,
`sender` TEXT,
`receiver` TEXT,
`body` TEXT,
`timestamp` INTEGER NOT NULL,
PRIMARY KEY(`id`)
);
This seems to be different from INTEGER NOT NULL PRIMARY KEY, even though I can't find any documentation for this behaviour in the SQLite documentation.
It seems I have to use #PrimaryKey (autogenerate=true) in order to make Room automatically generate primary key values. Looking at the generated database when using autogenerate=true, this generates the following SQL:
CREATE TABLE `SmsMessage` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`incoming` INTEGER NOT NULL,
`sender` TEXT,
`receiver` TEXT,
`body` TEXT,
`timestamp` INTEGER NOT NULL
);
It seems that autogenerate=true corresponds to SQLite AUTOINCREMENT. However, the SQLite documentation makes quite clear that AUTOINCREMENT isn't needed (and in most cases not recommended) in order to automatically generate unique primary keys. The purpose of AUTOINCREMENT is basically to prevent re-use of used but deleted primary keys.
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.
In SQLite, a column with type INTEGER PRIMARY KEY is an alias for the ROWID (except in WITHOUT ROWID tables) which is always a 64-bit signed integer.
On an INSERT, if the ROWID or INTEGER PRIMARY KEY column is not explicitly given a value, then it will be filled automatically with an unused integer, usually one more than the largest ROWID currently in use. This is true regardless of whether or not the AUTOINCREMENT keyword is used.
If the AUTOINCREMENT keyword appears after INTEGER PRIMARY KEY, that changes the automatic ROWID assignment algorithm to prevent the reuse of ROWIDs over the lifetime of the database. In other words, the purpose of AUTOINCREMENT is to prevent the reuse of ROWIDs from previously deleted rows.
So it seems that using #PrimaryKey(autogenerate=true) is usually not needed nor recommended. But only using #PrimaryKey alone will not automatically generate values at all.
How do I tell Room that what I want is 'id' INTEGER NOT NULL PRIMARY KEY?
That's not possible at the moment - the only option is AUTOINCREMENT. You can star the existing feature request for progress updates on support for this use case.

Can't find the syntax error in this SQLite statement

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.

SQLite PRIMARY key AutoIncrement doesn't work

I'm trying to a have a table with an auto incremented primary key. The SQL query for table creation is included.
Problem is the auto-increment does not work. Meaning when I insert a row with NULL as the value of conversation_id it just inserts null. I have this problem on multiple tables.
-- Table: conversations
CREATE TABLE conversations (
conversation_id INTEGER (64) PRIMARY KEY
UNIQUE,
target_id BIGINT (64),
sender_id BIGINT (64),
status STRING (16) NOT NULL
DEFAULT unseen,
is_group INTEGER (1) NOT NULL
DEFAULT (0),
last_update INTEGER (32) DEFAULT (0),
target_name STRING (64),
target_photo STRING (256),
unread_count INTEGER (10) DEFAULT (0),
last_message STRING (256)
);
The following is the method I use to insert into table:
public Conversation addConversation(Conversation conversation) {
SQLiteDatabase db = getWritableDatabase();
ContentValues row = new ContentValues();
row.put("target_id", conversation.getTargetID());
row.put("sender_id", conversation.getSenderID());
row.put("target_name", conversation.getTargetName());
row.put("target_photo", conversation.getTargetPhoto());
row.put("status", conversation.getStatus());
row.put("unread_count", conversation.getUnreadCount());
row.put("last_message", conversation.getLastMessage());
conversation.setConversationID(db.insert(TBL_CONVERSATIONS, null, row));
Log.d(TAG, "conversation added: "+conversation.getConversationID());
db.close();
return conversation;
}
The curious thing here is when I retrieve the insert id from insert method it returns the correct value, but the actual database field is null.
If I understand correctly A column declared INTEGER PRIMARY KEY will autoincrement. [Cite]
From documentation:
A table created using CREATE TABLE AS has no PRIMARY KEY and no
constraints of any kind. The default value of each column is NULL.
You don't have to add UNIQUE constraint on a COLUMN that has PRIMARY KEY constraint.
Explanation:
A UNIQUE constraint is similar to a PRIMARY KEY constraint, except
that a single table may have any number of UNIQUE constraints.
Instead add NOT NULL.
This is why:
According to the SQL standard, PRIMARY KEY should always imply NOT
NULL. Unfortunately, due to a bug in some early versions, this is not
the case in SQLite. Unless the column is an INTEGER PRIMARY KEY or the
table is a WITHOUT ROWID table or the column is declared NOT NULL,
SQLite allows NULL values in a PRIMARY KEY column. SQLite could be
fixed to conform to the standard, but doing so might break legacy
applications. Hence, it has been decided to merely document the fact
that SQLite allowing NULLs in most PRIMARY KEY columns.
I recommend using this Column definition:
CREATE TABLE conversations (
conversation_id INTEGER PRIMARY KEY NOT NULL AUTOINCREMENT,
...
}
Most likely the return value you are seeing is the row's ROWID. A ROWID is a hidden column available in every table, unless explicitly removed. According to the official documentation, when you define an INTEGER PRIMARY KEY, it should automatically become an alias for the ROWID. That's also why AUTOINCREMENT is not needed when you define your column in this way.
With one exception noted below, if a rowid table has a primary key
that consists of a single column and the declared type of that column
is "INTEGER" in any mixture of upper and lower case, then the column
becomes an alias for the rowid. Such a column is usually referred to
as an "integer primary key". A PRIMARY KEY column only becomes an
integer primary key if the declared type name is exactly "INTEGER".
Other integer type names like "INT" or "BIGINT" or "SHORT INTEGER" or
"UNSIGNED INTEGER" causes the primary key column to behave as an
ordinary table column with integer affinity and a unique index, not as
an alias for the rowid.
See: CREATE TABLE documentation
Either your column is not an INTEGER, or it is not a PRIMARY KEY. Taking a closer look at your create-statement I can see one or two possible culprits.
UNIQUE vs. PRIMARY KEY
A primary key is unique by default. According to the syntax definition (which you can find on the same documentation page as the citation above) you should choose either PRIMARY KEY or UNIQUE, not both.
COLUMN length restrictions
ROWID is already 64-bit by default. You have specified length 64, but lengths are not specified in bits. You may have specified a 64-byte integer here, which I'm sure was not intended. This should actually not be a problem however, since SQLite ignores length-constraints. So it is not meaningful to specify them.
TLDR
Replace this code:
conversation_id INTEGER (64) PRIMARY KEY UNIQUE
With this:
conversation_id INTEGER PRIMARY KEY AUTOINCREMENT
I just put autoincrement in the query and it works fine .
like this
id integer primary key autoincrement

Android Database SQLLite AutoIncrement not incrementing and primary constraint violated

im creating a Table with this command :
create table if not exists Event ( _id long INTEGER AUTO INCREMENT,repeatEvery long ,repeating int ,startTime long ,title text ,primary key (_id) );
also tried id without the _ prefix, and then i fetch all rows with
database.query("Event",null , null, null, null, null, null);
and then i go over the results printing the ID column :
if (c.moveToFirst()) {
do {
System.out.println(c.getLong(c.getColumnIndexOrThrow("_id")));
} while (c.moveToNext());
}
all of the results are zeros! idea any one?
SQLITE by default adds an INTEGER AUTOINCREMENT for you. Search for ROWID. The creation of a column that replicates this functionality will just be created as an alias to ROWID.
I did some more digging around and found out what some of the issues are. First of all, SQLITE is garbage.
Here is the correct SQL statement you need to use.
CREATE TABLE Event (_id INTEGER PRIMARY KEY AUTOINCREMENT,repeatEvery long ,repeating int ,startTime long ,title text)
I issued the one in your code sample, and it had the type of the _id column as "INTEGER AUTO INCREMENT". The SQLITE parser is very generous and accepted that as a datatype. It had no idea what to do with it, and just treated it as a blob, and none of the constraints worked. So, even though your DDL was incorrect, SQLITE was nice enough to take it's best guess at what was wrong and didn't bother to let you know. :[
If you print the schema of your apps' Event table, you'll should see the INTEGER AUTO INCREMENT issue.
Another issue to watch out for,
If you're writing your insert statements on your own, you need to write in one of these two ways.
insert into Event (repeatEvery, repeating, startTime, title) values (1,2,3, "title");
or
insert into Event values (NULL, 1,2,3, "title");
the SQLITE Helper class should handle this for you.
From the sqlite docs it looks like the definition should be changed a little.
the definition should probably be:
create table if not exists Event ( _id INTEGER PRIMARY KEY, repeatEvery long, repeating int, startTime long, title text );
Simply :
create table if not exists Event ( _id INTEGER PRIMARY KEY,repeatEvery long ,repeating int ,startTime long ,title text );
for some reason, should not declare column type...

Problem with inserting into android sqlite3 table that has composite primary key

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 ?

Categories

Resources