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


249

Oracle数据库中是否有任何布尔类型,类似于BITSQL Server中的数据类型?


7
不幸的是,引入Oracle时,它并不完全支持ANSI SQL:1999标准(en.wikipedia.org/wiki/SQL:1999)。
Jeffrey Kemp

2
另类观点(SQL为什么不应该有一个boolean类型):vadimtropashko.wordpress.com/2010/09/16/...
杰弗里·肯普

7
@JeffreyKemp那个博客是荒谬的。仅仅因为某些布尔值可以基于表中的其他字段来计算,并不意味着可以计算所有布尔值。例如,“ is_trusted_customer”,当且仅当一个人决定“我信任那个人”时,才为真。
2014年

2
@JeffreyKemp恭喜,您刚刚重新发明了C风格的布尔值(在这里使用ints代替)。我们绝对应该回到代码中。此外,如果共享表列和结果列之间的数据类型(来自SELECT),则参数完全崩溃,因为有时即使给定了其余参数,返回布尔值作为计算结果也是绝对合适的。
jpmc26 2015年

2
是。像布尔值这样的更多数据类型将提供更精确的表达能力-在那方面,您不会对我产生任何争议。我很高兴我们至少有一个DATE类型-想象着一直都在处理日期的字符串表示形式:)
Jeffrey Kemp 2015年

Answers:


277

Oracle的SQL(不是PL / SQL)不仅缺少布尔数据类型,而且对于使用什么数据,他们也没有明确的建议。请参见asktom上的该线程。从推荐CHAR(1) 'Y'/'N'它们可以切换到NUMBER(1) 0/1有人指出'Y'/'N'依赖英语的时间,而例如德国程序员可能会使用'J'/'N'

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


9
1/0,如果不是模棱两可的话,至少是模棱两可的。
亚当·穆什

15
但是''= NULL是错误的!''IS NULL为真。:)
Jim Davis 2010年

4
Michael-O:我已经看过几次了。对我来说,一直都是0/1,但是其他程序员更喜欢J / N。(我住在德语国家)
埃里希·基茨穆勒

11
@Irfy最近,我看到NF使用,因为ONOFF具有相同字母开头的...
JimmyB

7
有人可能会说,用“ T” /“ F”代替布尔值更有意义
Erich Kitzmueller

55

不。

可以使用:

IS_COOL NUMBER(1,0)

1 - true
0 - false

---享受甲骨文

按此处所述使用字符Y / N


6
我更喜欢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

38

根据Ammoq和kupa的回答,我们使用number(1),默认值为0,并且不允许为空。

这是一个添加列来演示:

ALTER TABLE YourSchema.YourTable ADD (ColumnName NUMBER(1) DEFAULT 0 NOT NULL);

希望这对某人有帮助。


17
请注意,您也可以在其中存储-1。你可能对以限制值增加一个检查约束,以0和1
大卫·阿尔德里奇

@DavidAldridge在布尔逻辑中,任何不为0(FALSE)的数字都等于1(TRUE),因此存储什么数字都没有关系,从而无需检查约束。添加从int返回布尔值的函数很简单:boolean intToBool(int in) { return (in != 0); }
Agi Hammerthief

3
@AgiHammerthief是的,但是如果您想使用“布尔值”列上的谓词查找行,则我想知道我的选项是ColumnName = 0or ColumnName = 1,而不是ColumnName = 0or ColumnName <> 0。最后一个的语义对程序员不友好。我还希望通过具有两个值来使查询优化程序更简单。
David Aldridge

14

不在SQL级别,这很可惜PLSQL中有一个


13

不,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' ));

9

不存在不存在布尔类型,但是您可以1/0(类型编号)或'Y'/'N'(字符类型)或'true'/'false'(类型varchar2)代替。



4

一个常见的节省空间的技巧是将布尔值存储为Oracle CHAR而不是NUMBER:


4
CHAR(1)和VARCHAR2(1)在空间使用方面相同。
托尼·安德鲁斯

3
正如我在此处了解到的那样docs.oracle.com/cd/E17952_01/refman-5.5-zh/char.html当我们讲一个char时,只有char和varchar之间存在区别-char使用1个字节,但是varchar使用1个字节用于空白空间一个字符+ 1个字节-> varchar(varchar2)使用2个字节表示1个字符<当char仅使用1个字节时
Artem.Borysov 2015年

@ Artem.Borysov:该手册适用于MySQL,而不适用于Oracle数据库
a_horse_with_no_name

3

仅仅因为还没有人提及它:使用RAW(1)似乎也是一种惯例。


1
raw(1)很棒,因为用户无法假设其中的内容,执行查询的人员必须了解raw(1)列中的内容并将其转换为有意义的内容。
2014年

13
<sarcasm>是的,它太棒了,您不能用它编写可移植的jdbc代码。</
sarcasm

@jacob-<sarcasm>这是一个了不起的主意!我们应该摆脱所有其他数据类型,并将所有内容存储在RAW列中!然后,NOBODY可能会任意曲解数据!</ sarcasm>
Bob Jarvis-恢复莫妮卡

想象一下,如果在oracle中有某种方法可以定义数据类型,那么我们可以创建一个bool类型来包装“ raw(1)”类型,将其命名为bool或boolean。然后,我们可以定义一个函数,根据内容打印“ true”或“ false”。
雅各布

-1
DECLARE
error_flag  BOOLEAN := false;
BEGIN

error_flag := true;
--error_flag := 13;--expression is of wrong type

  IF error_flag THEN 

UPDATE table_a SET id= 8 WHERE id = 1;

END IF;
END;

这个例子有效。我还注意到,我只能在PL / SQL中使用布尔类型。SQL中的布尔调用不会,并且会产生无效的关系运算符错误。
理查德·帕斯夸
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.