I am trying to have a column holding the timestamp value whose default value is today + a few days. Could this be done during table creation time?
Yes it can be done as in the following example:
sqlite> create table foo (i int, j text default (datetime('now', '+5 days')));
sqlite> insert into foo (i) values (1);
sqlite> select * from foo;
1|2012-04-11 07:49:04
sqlite> insert into foo (i) values (2);
sqlite> select * from foo;
1|2012-04-11 07:49:04
2|2012-04-11 07:49:14
If you only want to store the date part, use date instead of datetime. Here I use datetime to show that the default expression is evaluated when inserting in the table, not when the table is created.
Related
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;
I want to insert time value to SQLite. I searched about functions, modifiers, timestrings but I could not achieve to my aim. When I write my query, this does not record the '.323', only records '08:25:01'. I want to record '08:25:01.323'. My query is:
insert into table_name (column_name) values (time('08:25:01.323'))
I'm waiting for your help..
Store the time as a string and only parse it whe necessary.
sqlite> create table t (t text);
sqlite> insert into t values ('08:25:01.323');
sqlite> select * from t;
08:25:01.323
sqlite> select t, time(t) from t;
08:25:01.323|08:25:01
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);
When defining a relation, I want to update an attribute to the timestamp at insert. For example, a working table that I have right now
CREATE TABLE t1(
id INTEGER PRIMARY KEY AUTOINCREMENT,
time TIMESTAMP
DEFAULT CURRENT_TIMESTAMP,
txt TEXT);
This is updating a timestamp on insert, for example, insert into t1 (txt) values ('hello') adds the row 1|2012-07-19 08:07:20|hello|. However, I want to have this date formatted in unixepoch format.
I read the docs but this wasn't clear. For example, I modified the table relation to time TIMESTAMP DEFAULT DATETIME('now','unixepoch') but I get an error. Here, as in the docs, now was my time string and unixepoch was the modifier but it didn't work. Could someone help me how to format it as a unixepoch timestamp?
Use strftime:
sqlite> select strftime('%s', 'now');
1342685993
Use it in CREATE TABLE like this:
sqlite> create table t1 (
...> id integer primary key,
...> time timestamp default (strftime('%s', 'now')),
...> txt text);
sqlite> insert into t1 (txt) values ('foo');
sqlite> insert into t1 (txt) values ('bar');
sqlite> insert into t1 (txt) values ('baz');
sqlite> select * from t1;
1|1342686319|foo
2|1342686321|bar
3|1342686323|baz
See https://www.sqlite.org/lang_createtable.html#tablecoldef
If the default value of a column is an expression in parentheses, then the expression is evaluated once for each row inserted and the results used in the new row.
Note 'timestamp' is not a data type known to SQLite (see list here). The default value generated by strftime() would actually be stored as Text.
If it is important to store the value as a number instead of as a string, declare the field as an Integer and add a CAST() into the mix, like so:
create table t1(
...
ts_field integer(4) default (cast(strftime('%s','now') as int)),
...
);
Indeed strftime, which can also be used like so:
SELECT strftime('%s', timestamp) as timestamp FROM ... ;
Gives you:
1454521888
'timestamp' table column can be a text field even, using the current_timestamp as DEFAULT.
Without strftime:
SELECT timestamp FROM ... ;
Gives you:
2016-02-03 17:51:28
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.