简体   繁体   中英

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM