SQlite在FALSE和0之间的差异

时间:2015-07-20 11:45:55

标签: sqlite

这两个陈述似乎都有所不同,但我还不明白为什么:

ALTER TABLE FOO ADD COLUMN DELETED BOOLEAN NOT NULL DEFAULT FALSE

似乎表现得与以下不同:

ALTER TABLE FOO ADD COLUMN DELETED BOOLEAN NOT NULL DEFAULT 0

任何人都可以对此有所了解 - 我认为FALSE为0且TRUE为1 - 但这个布尔值似乎有> = 4个状态:

➜  ~  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

1 个答案:

答案 0 :(得分:3)

为什么SQLite允许这些ALTER TABLE语句运行如图所示我不知道,但这里的缺失部分是那些FALSETRUE值将被存储为字符串

在SQLite命令行工具中尝试:

CREATE TABLE test (id integer, xx boolean not null default TRUE);
INSERT INTO test (id) VALUES (1)
.dump

你会得到这个输出:

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;

如您所见,TRUE值存储为字符串。

现在,让我们尝试查询TRUE值:

SELECT * FROM test WHERE xx = TRUE

这会出现此错误消息:

Error: no such column: TRUE

简而言之,TRUEFALSE在SQLite SQL语法中不是布尔值的神奇常量。为什么ALTER TABLE语句允许在没有引号的情况下指定它们我不知道,这可能是一个很好的理由。

以下是我的评论中的示例:

ALTER TABLE test ADD COLUMN xy INTEGER NOT NULL DEFAULT MONKEYDOODLE;

.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;

最后一个难题是SQLite并没有真正阻止您在同一列中存储不同数据类型的值。

来自documentation

  

SQLite版本3数据库中的任何列(INTEGER PRIMARY KEY列除外)都可用于存储任何存储类的值。

您可以在此处看到此效果:

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);

这是.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;