SQLite insert primary key only - sqlite

I have a table that is only a single column, INTEGER PRIMARY KEY.
As it's an autoincrement, How do I insert a value?
I've tried
INSERT INTO Rule DEFAULT VALUES;
which runs but doesn't actually insert anything. any other ideas?
Thanks!

The following command creates a column named INTEGER with no type:
> CREATE TABLE wrong(INTEGER PRIMARY KEY);
> INSERT INTO wrong DEFAULT VALUES;
> INSERT INTO wrong DEFAULT VALUES;
> SELECT * FROM wrong;
INTEGER
----------
 
 
If you don't forget the column name, DEFAULT VALUES works just fine with an INTEGER PRIMARY KEY column:
> CREATE TABLE Rule(RuleID INTEGER PRIMARY KEY);
> INSERT INTO Rule DEFAULT VALUES;
> INSERT INTO Rule DEFAULT VALUES;
> SELECT * FROM Rule;
RuleID
----------
1
2

Insert a null:
sqlite> create table a(a integer primary key autoincrement);
sqlite> insert into a values(null);
sqlite> insert into a values(null);
sqlite> select * from a;
1
2

Related

SQlite difference between FALSE and 0

these both statements seem to make a difference, but I do not yet get why:
ALTER TABLE FOO ADD COLUMN DELETED BOOLEAN NOT NULL DEFAULT FALSE
seems to behave differently than:
ALTER TABLE FOO ADD COLUMN DELETED BOOLEAN NOT NULL DEFAULT 0
can anyone shed some light on this - I thought FALSE is 0 and TRUE is 1 - but this boolean seems to have >= 4 states:
➜ ~ sqlite3
SQLite version 3.8.7.4 2014-12-09 01:34:36
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> CREATE TABLE FOO ( id INTEGER );sqlite> INSERT INTO FOO ( id ) VALUES (1);
sqlite> select * from FOO;
1
sqlite> ALTER TABLE FOO ADD COLUMN DELETED BOOLEAN NOT NULL DEFAULT FALSE;sqlite> select * from FOO;
1|FALSE
sqlite> ALTER TABLE FOO ADD COLUMN DELETED2 BOOLEAN NOT NULL DEFAULT 0;
sqlite> select * from FOO;
1|FALSE|0
sqlite> ALTER TABLE FOO ADD COLUMN DELETED3 BOOLEAN NOT NULL DEFAULT TRUE;
sqlite> select * from FOO;
1|FALSE|0|TRUE
sqlite> ALTER TABLE FOO ADD COLUMN DELETED4 BOOLEAN NOT NULL DEFAULT 1;
sqlite> select * from FOO;
1|FALSE|0|TRUE|1
sqlite> select * from FOO WHERE DELETED;
sqlite> select * from FOO WHERE DELETED2;
sqlite> select * from FOO WHERE DELETED3;
sqlite> select * from FOO WHERE DELETED4;
1|FALSE|0|TRUE|1
Why exactly SQLite allows these ALTER TABLE statements to run as shown I don't know but the missing piece of the puzzle here is that those FALSE and TRUE values will be stored as strings.
Try this in the SQLite command line tool:
CREATE TABLE test (id integer, xx boolean not null default TRUE);
INSERT INTO test (id) VALUES (1)
.dump
You'll get this output:
sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE test (id integer, xx boolean not null default TRUE);
INSERT INTO "test" VALUES(1,'TRUE');
COMMIT;
As you can see, the TRUE value there is stored as a string.
Now, let's try to query for the TRUE value:
SELECT * FROM test WHERE xx = TRUE
this gives this error message:
Error: no such column: TRUE
So in short, TRUE or FALSE are not magical constants in SQLite SQL syntax for the boolean values. Why the ALTER TABLE statements allow for them to be specified without quotes I don't know, there's probably a good reason.
Here's the example from my comment:
ALTER TABLE test ADD COLUMN xy INTEGER NOT NULL DEFAULT MONKEYDOODLE;
Output from .dump:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE test (id integer, xx boolean not null default TRUE, xy INTEGER NOT
NULL DEFAULT MONKEYDOODLE);
INSERT INTO "test" VALUES(1,'TRUE','MONKEYDOODLE');
COMMIT;
One final piece of the puzzle is also that SQLite doesn't really prevent you from storing values of different data types in the same column.
From the documentation:
Any column in an SQLite version 3 database, except an INTEGER PRIMARY KEY column, may be used to store a value of any storage class.
You can see this in effect here:
CREATE TABLE test (id integer);
INSERT INTO test VALUES (1);
INSERT INTO test VALUES ('test');
INSERT INTO test VALUES (DATE());
INSERT INTO test VALUES (10.5);
This is the output from .dump:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE test (id integer);
INSERT INTO "test" VALUES(1);
INSERT INTO "test" VALUES('test');
INSERT INTO "test" VALUES('2015-07-20');
INSERT INTO "test" VALUES(10.5);
COMMIT;

Insert default values in SQLite2

How to crate a now row without knowing the any of the columns of the table and using default values therefore?
In sqlite3 I simply do:
sqlite> CREATE TABLE t ("id" INTEGER PRIMARY KEY, "text" TEXT DEFAULT "hello world");
sqlite> INSERT INTO t DEFAULT VALUES;
sqlite> SELECT * FROM t;
1|hello world
But in sqlite2.8.17 I get:
sqlite> INSERT INTO t DEFAULT VALUES;
SQL error near 'DEFAULT': Syntax error.
Is there a way to do this right in sqlite2 or do I need to give the values manually in the insert statement?
You have to specify at least one value; all the others will then get their default values.
The rowid automatically gets a value when you specify NULL, so you can use that one:
INSERT INTO t(id) VALUES(NULL);

sqlite - How to get INSERT OR IGNORE to work

I'm trying to insert data into a table. I would like to insert the row if the column doesn't have the data already - regardless of the other columns.
CREATE TABLE t (
id INTEGER PRIMARY KEY,
name VARCHAR,
other INT
);
INSERT OR IGNORE INTO t (name) VALUES ('a');
INSERT OR IGNORE INTO t (name) VALUES ('a');
INSERT OR IGNORE INTO t (name) VALUES ('a');
With the above snippet I end up with 3 rows, not 1 as I would have thought. If it matters the actual sql is happening inside of a INSTEAD OF INSERT trigger, this is just a simple test case.
Replace
CREATE TABLE t (
id INTEGER PRIMARY KEY,
name VARCHAR,
other INT
);
with
CREATE TABLE t (
id INTEGER PRIMARY KEY,
name VARCHAR UNIQUE,
other INT
);
Then you will get
sqlite> CREATE TABLE t (
...> id INTEGER PRIMARY KEY,
...> name VARCHAR UNIQUE,
...> other INT
...> );
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> INSERT OR IGNORE INTO t (name) VALUES ('a');
sqlite> select * from t ;
1|a|
That would only work for the primary key field or unique constraints:
The optional conflict-clause allows the specification of an
alternative constraint conflict resolution algorithm to use during
this one INSERT command.
Further:
The ON CONFLICT clause applies to UNIQUE and NOT NULL constraints
(and to PRIMARY KEY constraints which for the purposes of this section
are the same thing as UNIQUE constraints). The ON CONFLICT algorithm
does not apply to FOREIGN KEY constraints. There are five conflict
resolution algorithm choices: ROLLBACK, ABORT, FAIL, IGNORE, and
REPLACE. The default conflict resolution algorithm is ABORT.

Not empty string constraint in SQLite

Can I create a database constraint on a TEXT column in SQLite disallowing the value of the column to be empty string ""?
I want to allow the column to be null, but disallow empty string.
Yes you can:
sqlite> create table foo (bar TEXT, CHECK(bar <> ''));
sqlite> insert into foo values (NULL);
sqlite> insert into foo values ('bla');
sqlite> insert into foo values ('');
Error: constraint failed
You can use a CHECK constraint (http://www.sqlite.org/lang_createtable.html):
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> create table example(col, CHECK (col is null or length(col) > 0));
sqlite> insert into example values ('');
SQL error: constraint failed
sqlite> insert into example values (null);
sqlite> insert into example values ('sample');
sqlite> .nullvalue NULL
sqlite> select col from example;
NULL
sample
As far as i know doesn't exist a similar constraint in SQLite, but maybe you can workaround with a Trigger that on INSERT and/or UPDATE automatically change the string empty in NULL.

how do I override the autoincremented primary key when doing an insert

In MS SQL I would use
SET IDENTITY INSERT ON
How do I do something similar in SQLite. I am trying to upgrade a database and want to maintain the IDs from the original
Thanks
You don't need to set IDENTITY INSERT, because it is always possible to set the value explicitly. With SQLite, you can just insert into the ROWID column:
drop table test;
create table test(name varchar);
insert into test(name) values('Hello');
insert into test(rowid, name) values(10, 'World');
select rowid, name from test;
The same if you use an autoincrement primary key:
drop table test;
create table test(id integer primary key autoincrement, name varchar);
insert into test(name) values('Hello');
insert into test values(10, 'World');
select * from test;
See also http://www.sqlite.org/autoinc.html

Resources