How to define your specified attribute like StudentId in student table as Primary key in sqlite
CREATE TABLE Student(
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT
);
From the Sqlite spec:
One exception to the typelessness of
SQLite is a column whose type is
INTEGER PRIMARY KEY. (And you must use
"INTEGER" not "INT". A column of type
INT PRIMARY KEY is typeless just like
any other.) INTEGER PRIMARY KEY
columns must contain a 32-bit signed
integer. Any attempt to insert
non-integer data will result in an
error.
http://www.sqlite.org/datatypes.html
You can also place a primary key on the arbitrary blobish data eg:
CREATE TABLE Student(id PRIMARY KEY, name)
Its a bit risky cause
INSERT INTO Student(1, "hello")
INSERT INTO Student("1", "hello")
will result in two rows.
If you need a unique constraint on other stuff you can try using the Create Index command
CREATE TABLE Students (
StudentId INTEGER PRIMARY KEY,
Name VARCHAR(80)
)
is one simple way.
Related
If I have a non-integer primary-key the rowid is an auto-increment starting at 1.
sqlite> create table t1 (name text, documentid integer, primary key (name));
sqlite> insert into t1 (name, documentid) values ('max', 123);
sqlite> insert into t1 (name, documentid) values ('duf', 321);
sqlite> select rowid,* from t1;
1|max|123
2|duf|321
But if I have a INTEGER primary-key it seems the rowid is equal to it.
sqlite> create table t2 (name text, xid integer, primary key (xid));
sqlite> insert into t2 (name, xid) values ('max', 123);
sqlite> insert into t2 (name, xid) values ('duf', 321);
sqlite> select rowid,* from t2;
123|max|123
321|duf|321
Thats unexpected for me. I would expect rowid to behave like in the 1st sample.
Is that normal behaviour? Can I make it work like expected?
I am using SqlLite3 3.27
The problem is not the value as long it is uniqua (must be by definition of primary). But in JDBC I can not address ResultSet.getInt ("rowid") anymore - need to use getInt ("xid") instead" to make it work. Thats abnormal to a table with a non-integer primar-key.
An INTEGER PRIMARY KEY column is just an alias for the rowid. It acts the same (Having a value automatically assigned if left out when inserting a row), and doesn't even take up any extra space in the database. You can reference the column via its name, rowid, or any of the other standard aliases for rowid like oid.
From the documentation:
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.
If you just do
INSERT INTO t2(name) VALUES ('max');
a value will be automatically generated for xid instead of explicitly using the one provided in the insert like in your example.
Yes it's the normal behavior.
When you define an integer column xid as primary key, then xid is just an alias of rowid.
What you can do is define xid as UNIQUE and not PRIMARY KEY:
create table t2 (name text, xid integer unique)
Then you will have the functionality that you want, because the rowid will be a different auto increment column.
Or define xid as TEXT:
create table t2 (name text, xid text, primary key (xid));
In this case also rowid is a different column and don't worry about the data you store in xid.
You can treat this column just like an integer column so you can perform any arithmetic calculation and aggregation.
You can find more here: https://www.sqlite.org/rowidtable.html
CREATE TABLE resource_sync
(
_id INTEGER UNIQUE ON CONFLICT REPLACE PRIMARY KEY,
status_id INTEGER,
result_id INTEGER
);
In case two equal _id values get inserted, SQLite would throw an exception:
[13:39:48] Error while executing SQL query on database 'test': UNIQUE
constraint failed: resource_sync._id
However, it allows for desired replaces in case primary key declaration is removed from table creation SQL.
Why is that?
Thanks.
UNIQUE is ignored on primary keys.
The correct syntax, as shown in the documentation, is:
CREATE TABLE resource_sync
(
_id INTEGER PRIMARY KEY ON CONFLICT REPLACE,
status_id INTEGER,
result_id INTEGER
);
I have a table created as:
create table association (_id integer unique primary key autoincrement , id_rules integer, id_places integer)";
To avoid replication of entry, I use the statement INSERT OR IGNOR, but it doesn't work. For example,
value (id_rules , id_places) = ("11","1") alredy in table, but using:
INSERT OR IGNORE INTO association (id_rules , id_places) VALUES ("11","1")
a new row is created.
Please, do anyone Know hwere is my mistake?
INSERT OR IGNORE will ignore any rows that would violate a UNIQUE constraint.
The only such constraint is on the _id column, which you did not specify.
If you want to prevent duplicates in those two columns, you have to add a constraint for them to the table definition:
CREATE TABLE association (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
id_rules INTEGER,
id_places INTEGER,
UNIQUE (id_rules, id_places)
);
CREATE TABLE IF NOT EXISTS fw_users (id INT(64) NOT NULL PRIMARY KEY AUTOINCREMENT, auth CHAR(64) UNIQUE, money INT(32) DEFAULT '0', unlocks VARCHAR(8000))
I can't see any error in it, but SQLite throws an error:
Query failed! AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY
It doesn't make sense, id IS an integer
INT(64) isn't close enough; it must be INTEGER.
The SQLite notation is INTEGER PRIMARY KEY. Docs reference:
If you declare a column of a table to be INTEGER PRIMARY KEY, then whenever you insert a NULL into that column of the table, the NULL is automatically converted into an integer which is one greater than the largest value of that column over all other rows in the table, or 1 if the table is empty. Or, if the largest existing integer key 9223372036854775807 is in use then an unused key value is chosen at random.
[...]
CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b INTEGER
);
Using SQLite3, if you create a table like this:
CREATE TABLE MyTable (
id int primary key,
--define other columns here--
)
it turns out sqlite3_column_type(0) always returns SQLITE_NULL.
If I read on a bit, this may well be by design because this column is actually an alias to the internal rowid field.
Still, what is the programatical way to determine a certain column is an/the alias to the rowid field?
(Perhaps related, can I use sqlite3_column_type(x)==SQLITE_NULL to determine if the field of the current record holds NULL?)
According to http://www.sqlite.org/draft/lang_createtable.html#rowid
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.
So in your case it's "int" so invalid alias