Oracle数据库中是否有布尔类型?

337

Oracle数据库中是否有类似于Ms SQL Server中BIT数据类型的布尔类型?


9
很遗憾,当引入 ANSI SQL:1999 标准时(http://en.wikipedia.org/wiki/SQL:1999),Oracle 并没有完全支持该标准。 - Jeffrey Kemp
2
另一种观点(为什么 SQL 不应该 有布尔类型):http://vadimtropashko.wordpress.com/2010/09/16/on-boolean-datatype-in-sql-and-beyond/ - Jeffrey Kemp
18
@JeffreyKemp 这篇博客毫无意义。仅仅因为一些布尔值可以基于表中的其他字段计算得出,并不意味着所有布尔字段都可以被计算。例如,“is_trusted_customer”字段,只有在人类决定“我信任那个人”的情况下才为真。 - Jay
4
恭喜你,你刚刚重新发明了C语言风格的布尔值(使用整数而不是布尔类型)。在编码中我们应该回到那种方式。另外,如果表列和结果列(从SELECT中)之间共享数据类型,则该论点完全崩溃,因为有时将布尔值作为计算结果返回是绝对合适的,即使考虑到其他论点的情况。 - jpmc26
4
是的。更多像布尔值这样的数据类型会给予更精确的表达能力 - 在这方面我不会反驳。我只是很高兴我们至少有一个“日期”类型 - 想象一下如果一直处理日期的字符串表示 :) - Jeffrey Kemp
显示剩余12条评论
11个回答

360

在23c版本(2023年)之前,Oracle的SQL(而不是PL/SQL)中不仅缺少布尔数据类型,而且他们也没有明确的建议要使用什么替代方法。请参见asktom上的this thread。从推荐CHAR(1) 'Y'/'N'到当有人指出'Y'/'N'取决于英语,而例如德国程序员可能会使用'J'/'N'时,他们转而推荐NUMBER(1) 0/1

最糟糕的是,他们像捍卫''=NULL愚蠢决定一样捍卫这个愚蠢决定。


Oracle 23c 最终在所有上下文中支持布尔数据类型,以及其他一些它与其他数据库相比著名缺乏的功能。

SQL> select true;

TRUE
-----------
TRUE

SQL> create table test1(a boolean);

Table created.

SQL> insert into test1 values (true),(false),(to_boolean(0)),(to_boolean('y'));

4 rows created.

但是空字符串问题将永远不会改变。


17
1/0的含义,如果不算模棱两可,至少也是不那么模棱两可的。 - Adam Musch
30
“但 ''=NULL 是假的!'' IS NULL 是真的。 :)”意思是,''(空字符串)等于 NULL 是错误的逻辑判断,而 '' 是否为 NULL 则是正确的逻辑判断。最后笑脸表示开玩笑或者开心的情绪。 - Jim Davis
12
最近我看到人们使用 NF 代替 ONOFF,因为 ONOFF 首字母相同。 - JimmyB
9
有人可能会认为,相较于布尔值,使用'T'/'F'作为替代更加合理。 - Erich Kitzmueller
4
我知道你的确是什么意思,但我想要讽刺地强调Oracle那些奇怪的观点。 - GingerHead
显示剩余14条评论

81

不行。

可以使用:

IS_COOL NUMBER(1,0)

1 - true
0 - false

--- 享受使用 Oracle

或者像这里描述的那样,使用字符 Y/N


7
我更喜欢使用char(1),因为它占用的空间较少。你可以通过以下方式进行确认:create table testbool (boolc char(1), booln number(1)); insert into testbool values ('Y', 1 ); select dump(boolc), dump(booln) from testbool;其中,CHAR类型的存储方式为:Typ=96 Len=1: 89,而NUMBER类型的存储方式为:Typ=2 Len=2: 193,2。至少在12c版本中,NUMBER(1)类型可能会占用2个字节的空间。 - phil_w
4
来自Java背景,JDBC规范中的ResultSet.getBoolean()指定:如果指定的列具有CHAR或VARCHAR数据类型并包含“0”,或具有BIT、TINYINT、SMALLINT、INTEGER或BIGINT数据类型并包含0,则返回false值。如果指定的列具有CHAR或VARCHAR数据类型并包含“1”,或具有BIT、TINYINT、SMALLINT、INTEGER或BIGINT数据类型并包含1,则返回true值。-- 基于此,我建议使用0/1解决方案而不是Y/N。即使使用CHAR列,最好也使用数字。 - Crusha K. Rool
作为一名老练的C程序员,我更喜欢在逻辑语句中使用TRUE = 1和FALSE = 0,任何非零值都是真。数字与字符之间存在速度与大小的权衡,因为数字永远不需要经过代码集转换,而字符经常需要。 - Chris Golledge
没有检查约束条件,这是一个不可靠的决定。 - Simon Logic

50
根据Ammoq和kupa的答案,我们使用默认为0且不允许空值的number(1)。
以下是一个演示“添加列”的示例:add column
ALTER TABLE YourSchema.YourTable ADD (ColumnName NUMBER(1) DEFAULT 0 NOT NULL);

希望这能帮助到某个人。


19
请注意,您也可以在其中存储-1。您可能需要添加一个检查约束来将值限制为0和1。 - David Aldridge
2
在布尔逻辑中,任何不为0(假)的数字都等同于1(真),因此存储的数字是什么并不重要,从而无需进行检查约束。添加一个从int返回布尔值的函数很容易:boolean intToBool(int in) { return (in != 0); } - Agi Hammerthief
6
@AgiHammerthief 是的,但如果你想使用"boolean"列上的谓词来查找行,我更想知道我的选项是 ColumnName = 0ColumnName = 1 ,而不是 ColumnName = 0ColumnName <> 0。后者的语义对程序员来说不太友好。我还希望通过只有两个值来使查询优化器更简单。 - David Aldridge
不支持在数据库中使用普通的真/假布尔值是一个非常愚蠢的决定 :/ 整个 IT 都建立在布尔值之上。我们需要从程序中存储一些数据 - 哦等等,不支持正常的布尔值怎么办。这会很有趣!xDD - JsonKody

20

在Oracle数据库中没有布尔类型,但可以这样实现:

可以在列上设置检查约束。

如果您的表没有检查列,可以添加它:

ALTER TABLE table_name
ADD column_name_check char(1) DEFAULT '1';
当您添加一个注册时,默认情况下,此列的值为1。
在这里,您可以设置一个检查,限制该列的值只能为1或0。
ALTER TABLE table_name ADD
CONSTRAINT name_constraint 
column_name_check (ONOFF in ( '1', '0' ));

15

很遗憾,这不是在SQL层面完成的, 但在PL/SQL中有相应的功能。


9

不存在布尔类型,但你可以使用1/0(数字类型),或者'Y'/'N'(字符类型),或者'true'/'false'(varchar2类型)。


6

在PL/SQL中有一个布尔类型,但没有可以用作列数据类型的布尔类型。


5

如果你正在使用Java和Hibernate,那么使用NUMBER(1,0)是最好的方法。正如这里所示,Hibernate会自动将该值转换为布尔类型。


4

一种常见的节省空间的技巧是将 boolean 值存储为 Oracle 的 CHAR,而不是 NUMBER:


4
CHAR(1)和VARCHAR2(1)在空间使用上是相同的。 - Tony Andrews
3
根据https://docs.oracle.com/cd/E17952_01/refman-5.5-en/char.html所述,当我们存储一个字符时,char和varchar之间仅存在差异 - char使用1个字节,而varchar使用1个字节的空格+ 1个字节的一个字符-> varchar(varchar2)对于1个字符使用2个字节,而char只使用1个字节。 - Artem.Borysov
2
@Artem.Borysov:那个手册是针对MySQL的,不是Oracle数据库。 - user330315

3
只是因为还没有人提到它:使用RAW(1)似乎也是常见的做法。

1
raw(1)很棒,因为用户无法假设其中包含什么内容,执行查询的人必须理解raw(1)列中的内容并将其转换为有意义的东西。 - Jay
15
“是啊,太棒了,你不能用它编写便携式的JDBC代码。” - chubbsondubs
1
@jacob - <讽刺>这是个绝妙的想法!我们应该摆脱所有其他数据类型,将一切都存储在RAW列中!然后没有人可以随意歪曲数据!</讽刺> - Bob Jarvis - Слава Україні
1
想象一下,如果 Oracle 中有一种定义数据类型的方法,这样我们就可以创建一个包装了“raw(1)”类型,并将其命名为 bool 或 boolean 的布尔类型。然后,我们可以定义一个函数来根据内容打印“true”或“false”。 - Jay

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