Is there any boolean type in Oracle databases?
Oracle数据库中是否有类似于MS SQL Server中的BIT数据类型的布尔类型?
- 不幸的是,当引入ANSI SQL:1999标准(en.wikipedia.org/wiki/sql:1999)时,Oracle并不完全支持它。
- 备选视角(为什么SQL不应该有布尔类型):vadimtropashko.wordpress.com/2010/09/16/…
- @Jeffreykemp认为博客是非感性的。仅仅因为一些布尔值可以基于表中的其他字段进行计算,并不意味着所有布尔值字段都可以计算。例如,"是你信任的顾客",如果并且只有当一个人决定,"我信任那个人",这才是真的。
- @雅各布(只是在这里扮演魔鬼的拥护者)是"值得信赖的顾客",可以重新设计为"顾客信任度评分>0":)P.S.我不一定同意这篇文章。
- Oracle中布尔字段可能重复
- @Jeffreykemp恭喜你,你刚刚重新设计了C型的胸部(你用的是int)。我们绝对应该回到代码中的那些。此外,如果表列和结果列(来自SELECT的)之间的数据类型是共享的,则参数完全崩溃,因为有时甚至给定参数的其余部分,返回布尔值作为计算结果是绝对合适的。
- 不,我什么也没发明。在表达式"score>0"中,score是一个数字,而不是布尔值(C样式或其他)。
- @Jeffreykemp我的观点是,如果应用程序和用户不关心分数的大小(这是唯一一次考虑使用布尔值而不是数字),那么它实际上是一个布尔值,其中所有大于0的都是真的,0是假的。如果不改进系统,这样的选择实际上会模糊列的真正含义。(我知道你不一定同意这篇文章的观点,所以我很抱歉我的措辞很私人。我是想讨论这个概念。)
- 对。更多的数据类型,如布尔值,将提供更精确的表达能力——在这方面,我不会给你任何论据。我很高兴我们至少有一个DATE类型-想象一下必须一直处理日期的字符串表示:)
- 更多的数据类型未必更好。在Oracle中拥有一个单数字数据类型是一件好事。说到日期,如果日期只是秒数(有一些支持的功能),那么我们就不必一年两次地调整无数的时钟了。
- @Tegirineashi Oracle实际上支持SQL中的数字、二进制浮点数和二进制双精度数。但是后两个没有用。
- 不,布尔数据类型不增加任何表达能力。它只是0和1值的语法糖。事实上,与逻辑学家不同的是,数学家把布尔函数称为z/(2)的元素。从实践的角度看,布尔连词怎么样?它是一个简单的乘法xy。分开怎么样?它是X+Y-XY。否定?1-X。
- @Jeffreykemp,除非你在讽刺DATE数据类型:如何使用'01-jan-1970'创建日期或不使用字符串表示日期?老实说,我宁愿将Unix时间戳存储为NUMBER值。(这是我被教导要做的,从来没有人给过我不做的理由。)
- @不,我不是在讽刺你。DATE数据类型是SQL中最好的部分之一。(顺便说一句,'01-JAN-1970'是字符串,而不是日期;to_date返回DATE而不是字符串)DATE值明确地表示日期(实际上是日期/时间)(字符串和数字不能做的事情),基本比较和算术运算符以有用的方式处理它,而不能处理字符串或数值。
- @Jeffreykemp unix timestamps use numbers unambigusly(number of seconds or millesconds before or since 01 Jan 1970,UTC/GMT,or 0).两者都用弦乐为一种有其他(内部)代表性的数据类型提供价值,而这种代表性在简单/视觉检查中并不明显。任何体面的编程语言(包括SQL)都应该有EDOCX1&2&EDOCX1&3〕功能部分,其中应允许特定日期格式,TZ&Amp胶印。
- 在毫秒内,x + 1将在x之后返回1毫秒。自从x代表日期以来,假设毫秒内的毫秒数没有增加。在1752年的案例中,联合国大学的01 January 1752 00:00:00 GMT+00:00是-6879427200000。一个神谕日期将以01-Jan-52',这是模糊不清的,给出了一年中精确度的缺陷,以及显示时间、分钟、秒和GMT胶印的失败。
- @Agihammerthief,no-Oracle does not represent dates as strings.当你正确地离开时,只是一个字符串,而不是一个日期,而且肯定是模糊不清的。Oracle does not use strings like this to represent dates.
不仅Oracle的SQL中缺少布尔数据类型(而不是pl/sql),而且他们也没有明确的推荐使用什么。请看asktom上的这条线。当有人指出'Y'/'N'依赖于英语时,他们不再推荐CHAR(1) 'Y'/'N',转而推荐NUMBER(1) 0/1,而德国程序员可能使用'J'/'N'。
最糟糕的是,他们捍卫这个愚蠢的决定,就像捍卫江户的愚蠢一样。
- 1/0如果不模棱两可,至少不那么模棱两可。
- 我也更喜欢1/0,但当然,你也会发现那些有视觉基础背景的人选择-1/0。IMO对于这个问题只有一个明智的解决方案:Oracle应该创建一个布尔数据类型。当几乎所有其他RDBMS都有一个RDBMS时,就不会那么困难了。
- 但''=null为false!''为空为真。:)
- 迈克尔-欧:我已经看过好几次了。对我来说,它一直是0/1,但其他程序员更喜欢J/N(我住在德语国家)。
- 我见过讲法语的程序员也使用O/N…(O为OUI)
- 作为一种娱乐,请允许我提一下,我曾经必须在一张表的一行中存储大量的布尔值(数百),并成功地将它们组合成少量的数字类型,通过使用嵌入在视图中的位和函数分别访问和索引它们。我不确定我是否愿意再来一次,但那时候很酷。一个特别好的特性是能够找到与这些布尔值上的100+谓词有效匹配的行,并使用一个形式的谓词:"my_number=45439794"。
- 我很想看到一种语言突然出现,其中yes和no以同一个字母开头…(快速的谷歌搜索没有帮助找到一个)
- @最近,我看到N和F被使用,因为ON和OFF以同一个字母开头…
- @汉诺宾德很出色,谢谢你:-)
- 使用与"Y/N"不同的语言,因为你的母语不是英语,这和出于同样的原因拒绝使用"select"、"from"、"where"等有意义。
- @ocramot:对于许多讲德语的程序员(在讲德语的国家工作,为讲德语的客户开发软件…),使用"j"和"n"是完全有意义的。这是你必须期待的。顺便说一句,在SAP的世界里,惯例是用"X"表示真,用"X"表示假。
- @Ammoq我知道我应该期待它,我住在意大利,我习惯于用"s/n"作为选项;但我仍然觉得在英语中所有其他单词都是奇怪的,尤其是如果它是布尔值的替代词。
- 有人可能会说,作为布尔值的替代品,"t'/f"更有意义。
- 当使用类似ORM的实体框架时,这是非常愚蠢的。你必须穿过铁环才能在疯狂之上绘制地图。
- 答案中有一个小问题,因为''=NULL不是真的,但'' IS NULL是真的。)
- @姜饼头谢谢你的评论。=不是字面上的SQL运算符,而是逻辑上的—正如在Oracle中对待空值和"相同"。
- 是的,我知道你的确切意思,但我想讽刺地强调先知的古怪观念。
不。
可以使用:
1 2 3 4
| IS_COOL NUMBER(1,0)
1 - TRUE
0 - FALSE |
——享受甲骨文
或者使用这里描述的字符y/n
- 我更喜欢char(1),因为它使用的空间更少。您可以这样检查:create table testbool (boolc char(1), booln number(1)); insert into testbool values ('Y', 1 ); select dump(boolc), dump(booln) from testbool;存储字符:Typ=96 Len=1: 89和数字:Typ=2 Len=2: 193,2至少在12c中,数字(1)可以使用2个字节…
根据ammoq和kupa的答案,我们使用数字(1),默认值为0,不允许空值。
下面是一个要演示的添加列:
1
| ALTER TABLE YourSchema.YourTable ADD (ColumnName NUMBER(1) DEFAULT 0 NOT NULL); |
希望这能帮助别人。
- 请注意,您也可以在其中存储-1。您可以对其添加一个检查约束,以将值限制为0和1。
- @在布尔逻辑中,任何非0(假)的数字都等于1(真),因此无论存储什么数字,都无需检查约束。添加一个从int返回布尔值的函数是很简单的:boolean intToBool(int in) { return (in != 0); }。
- @AgiHammer窃贼是正确的,但是如果您想使用"布尔"列上的谓词查找行,我宁愿知道我的选项是ColumnName = 0或ColumnName = 1,而不是ColumnName = 0或ColumnName <> 0。最后一个语义对程序员不友好。我还希望通过有两个值来让查询优化程序更简单。
不是在SQL级别,这是一个遗憾但是PLSQL中有一个
不,Oracle数据库中没有布尔类型,但可以这样做:
可以在列上放置检查约束。
如果您的表没有复选列,可以添加它:
1 2
| ALTER TABLE TABLE_NAME
ADD column_name_check CHAR(1) DEFAULT '1'; |
添加寄存器时,默认情况下,此列获取1。
在这里,您只需输入1或0,就可以设置限制列值的检查。
1 2 3
| ALTER TABLE TABLE_NAME ADD
CONSTRAINT name_constraint
column_name_check (ONOFF IN ( '1', '0' )); |
不,不存在Boolean类型,但您可以使用1/0(类型编号)、或"y''n'(类型char)或"true''false'(类型varchar2)来代替它。
pl/sql中有一个布尔类型可供使用,但没有一个可以用作列的数据类型。
一个常见的节省空间的技巧是将布尔值存储为Oracle字符,而不是数字:
- char(1)和varchar2(1)在空间使用上是相同的。
- 正如我在这里学到的,docs.oracle.com/cd/e17952_01/refman-5.5-en/char.html当我们报道一个字符时,char和varchar之间只存在差异-char使用1个字节,但是varchar使用1个字节作为空白空间+1个字节作为一个字符->varchar(varchar2)使用2个字节作为1个字符<当char仅使用1个字节时
只是因为还没有人提到它:使用raw(1)似乎也是常见的做法。
- raw(1)很好,因为用户不能假定其中包含什么,执行查询的人必须理解raw(1)列中的内容,并将其转换为有意义的内容。
- yes it's so great that you can't write portable JDBC code with it.
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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中的布尔调用不会,并且会产生一个无效的关系运算符错误。