SQLite 中是否有布尔字面量?

85

我知道boolean列类型,但在SQLite中是否有boolean字面值呢?在其他编程语言中,这可能是truefalse。显然,我可以使用01,但我倾向于尽可能避免所谓的“魔数”。

这个列表来看,它似乎存在于其他SQL实现中,但不在SQLite中。(我使用的是SQLite 3.6.10)


2
布尔字面量不等于布尔数据类型。在我看来,它不应该被关闭为重复项。 - Lukasz Szozda
12个回答

105

来自文档的第 1.1 布尔数据类型 部分:

SQLite 没有单独的布尔存储类。相反,布尔值被存储为整数 0(false)和 1(true)。

因此,看起来你只能使用 01


12
我在阅读那份文档后来到了这里,但我认为文档对于SQLite的SQL解析器是否将01分别与标识符falsetrue进行了别名处理非常模糊不清。请注意,我的翻译旨在使内容更加通俗易懂,但不改变原始含义。 - O. R. Mapper
8
遗憾的是,这个答案没有回答问题,问题不是关于存储类型/列类型,而是关于TRUEFALSE文本的使用,这些文本符合SQL标准,根据Postgresql文档(https://www.postgresql.org/docs/8.1/static/datatype-boolean.html)提供。 - Lloeki
1
@Lloeki - 很遗憾,你在SQLite问题中引用了Postgresql文档... - Justin Ethier
1
抱歉,我指的是符合ANSI SQL标准的,但是我没有找到一个明确的参考资料,所以只好借鉴了PostgreSQL文档中的一条注释。我的评论开始变成了一个答案,所以我打算简短地结束评论并转而撰写一个完整的回答,以便回答实际问题。 - Lloeki
2
@Lloeki - 就 ANSI SQL 兼容性而言,SQLite 在布尔值方面并不符合标准,但是他们的文档是权威的来源。在这方面,你提供的 SQLite 关键字列表链接非常有用,可以明确 TRUEFALSE 不被支持。 - Justin Ethier
4
@Lloeki SQLite现在支持字面值 :) 请查看 https://dev59.com/9XE85IYBdhLWcg3w_I38#54223589 - Lukasz Szozda

32
在SQLite中是否有布尔字面量?
正如Justin Ethier的答案所述,SQLite没有专门的布尔数据类型。但是,从SQLite 3.23.0开始,它支持true/false字面量:
  1. 将TRUE和FALSE识别为常量。(为了兼容性,如果存在名为“true”或“false”的列,则标识符将引用列而不是布尔常量。)
  2. 支持运算符IS TRUE、IS FALSE、IS NOT TRUE和IS NOT FALSE。
SELECT true AS t, false AS f;

SELECT 'condition is true'
WHERE 1 IS NOT FALSE;

CREATE TABLE a (id INT, b BOOLEAN DEFAULT(TRUE));
INSERT INTO a(id) VALUES(100);
SELECT * FROM a;
-- id  b
-- 100 1

SELECT * FROM a WHERE true;
-- id  b
-- 100 1

dbfiddle.com演示


10

1.1 布尔数据类型

SQLite没有单独的布尔存储类。相反,布尔值作为整数0(假)和1(真)存储。

文档


6
我在阅读了该文档的一部分后来到这里,但我认为文档对于SQLite的SQL解析器是否将0和1与标识符falsetrue同义非常含糊不清。 - O. R. Mapper
5
是的,根据这个问题的答案,我也是这么想的,但是文档中引用的部分在我看来非常不清楚。它说布尔值分别以数字01的形式存储,然后指出这些数字匹配falsetrue。那里的falsetrue是什么?对读者的自然语言提示,还是SQLite的SQL解析器理解的常量/别名?正如我所说,写得非常模糊不清。 - O. R. Mapper
5
不是这么说的。这可能只是SQLite SQL解析器理解的一个“false”值,但并不清楚。这就是为什么阅读文档的这部分让我完全不知所措,并在寻找一些额外的确认,即在SQLite中没有类似“false”和“true”的常量,这也是我来到这里的原因。 - O. R. Mapper
3
有些C编译器可能会引入伪布尔常量,就像一些SQL解析器可能会引入伪布尔常量一样。 - O. R. Mapper
1
@Andrey C可能没有显式的布尔类型,但它有布尔值(即无论您在if条件中放置什么,比如比较、整数或函数调用的结果,都被视为布尔值,因为它只能产生两种效果),因此定义true和false的别名是有意义的。同样,SQLite没有布尔类型,但它也有布尔值,因此语言设计者在那里定义别名也是有意义的。“自己定义常量与在语言中拥有常量是不同的事情”,是的,但有标准库定义。 - Parthian Shot
显示剩余7条评论

9
这个问题明确与列类型(即存储方式)无关,而是与TRUEFALSE字面值的使用有关(即解析器方面),它们符合SQL标准,如PostgreSQL关键字文档所述(该文档还包括参考表中的SQL-92、SQL:2008和SQL:2011列)。
SQLite文档列出了所有支持的关键字,但该列表既不包含TRUE也不包含FALSE,因此在这方面,SQLite遗憾地不符合标准。
您还可以轻松测试并查看解析器如何失败,因为它希望令牌成为列名。
$ sqlite3 :memory:
SQLite version 3.14.0 2016-07-26 15:17:14
sqlite> CREATE TABLE foo (booleanish INT);
sqlite> INSERT INTO foo (booleanish) VALUES (TRUE);
Error: no such column: TRUE

这是正确的答案。Sqlite客户端库有时会抑制此错误(WTF),但正如您所展示的,如果在命令行sqlite3应用程序中运行它,则不喜欢“true”或“false”文字。 - Andrew Koster
根据Lukasz的回答,从SQLite版本3.23开始,这不再是正确的答案。 - AndyMcoy

4
正如其他人所指出的,SQLite不支持特定的布尔存储类型,并且OP明确承认了这一事实。但是,这与SQLite是否支持布尔字面量和综合无关。
对于任何想知道答案的人,自从SQLite 3.23以来,您可以使用布尔字面量TRUE和FALSE进行布尔综合,并且它将按照您的预期工作。
例如,您可以执行以下操作:
SELECT * FROM blah WHERE some_column IS FALSE;
SELECT * FROM blah WHERE some_column IS TRUE;
如果您在使用0表示false和1表示true,则会按您的预期工作。
根据我的测试,以下是SQLite匹配各种值的方式:
任何非零的数字、整数或实数:IS TRUE
任何零的数字、整数或实数:IS FALSE
空值:IS NULL。不匹配IS TRUE或IS FALSE。
任何不能解析为数字值的文本:IS FALSE。即使像“t”、“TRUE”、“true”、“True”这样的值也会匹配IS FALSE。
看起来像一个数字的TEXT(例如“0”,“1”,“5”):行为类似于NUMERIC,如上所述。
BLOB:未经测试。

0

在编程中,没有布尔数据类型。只有5种类型,在这里列出。整数可以以不同的宽度存储在磁盘上,最小的宽度为1字节。然而,这是一个实现细节:

"但是,一旦从磁盘读取INTEGER值并进入内存进行处理,它们就会转换为最通用的数据类型(8字节有符号整数)."

考虑到这一点,没有布尔字面量也就不足为奇了。


2
另一方面,尽管SQLite不是这五种类型之一,但它支持日期时间,因此这个答案并不确定。https://www.sqlite.org/datatype3.html#datetime - Mooing Duck

0

我注意到在安卓的sqlite中,我可以声明一个布尔列类型而不会出错,并且它似乎工作正常。我还尝试将该列定义为“int”并存储java布尔值。我下载了数据库并确认我正在写入该列的“true”。我认为它只是有效的。


1
“CREATE TABLE a (b BOOLEAN DEFAULT(TRUE));” 失败是因为它无法理解“TRUE”。 - Mooing Duck
1
@MooingDuck 现在你可以 https://dev59.com/9XE85IYBdhLWcg3w_I38#54223589 :) - Lukasz Szozda

0

在创建表时,您可以使用BOOLEAN

sqlite3 :memory:
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> CREATE TABLE test (mybool BOOLEAN);

但这不是一个真正的数据类型,在表的SQL描述中,我们会得到类似这样的内容:

"mybool" BOOLEAN NOT NULL CHECK(mybool IN(0,1))

基本上,我们创建了一个SQL约束条件,该值应为0或1。因此,使用TRUE / FALSE将弹出错误:

sqlite> INSERT INTO test(mybool) VALUES (TRUE);
Error: no such column: TRUE

所以,我们可以使用关键词 BOOLEAN 但必须使用 0/1,因为它不是一个“真正”的数据类型。
在使用 sqlalchemy 时,我们可以毫无问题地使用数据类型 BOOLEAN。

-1

SQLite3仅支持5种数据类型。

来自官方SQLite3文档。 “在SQLite数据库中存储的每个值(或由数据库引擎操作的值)都具有以下存储类之一:

NULL. The value is a NULL value.

INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value."

如果你要存储1和0,那么SQLite将使用1字节的存储空间。这并不差。

官方文档链接:http://www.sqlite.org/datatype3.html

反过来说,尽管不是这五种类型之一,但SQLite支持日期时间,因此这个答案并不确定。sqlite.org/datatype3.html#datetime - Mooing Duck

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接