为什么Oracle 9i将空string视为NULL?
我知道它确实认为是NULL
,但是这并不能告诉我为什么会这样。 据我了解的SQL规范,“是不是一样的NULL
– 一个是有效的数据,另一个表明没有相同的信息。
随意推测,但请指出是否是这种情况。 如果有来自甲骨文的人可以对此发表评论,那太棒了!
我相信答案是Oracle非常非常老。
早在SQL标准出现之前,Oracle做出了devise决定: VARCHAR
/ VARCHAR2
列中的空string是NULL
并且只有一种NULL的含义(有关系理论家可以区分从未提示,答案存在但用户不知道的数据,没有答案的数据等等,所有这些都构成NULL
意义)。
当SQL标准出现并同意NULL
和空string是不同的实体时,已经有Oracle用户认为这两个代码是相同的。 因此,Oracle基本上有了打破现有代码,违反SQL标准或引入某种初始化参数的选项,这些参数将改变潜在的大量查询的function。 违反SQL标准(恕我直言)是这三个选项中最小的破坏性。
Oracle已经开放了VARCHAR
数据types在将来的发行版中改变以符合SQL标准的可能性(这就是为什么每个人都使用Oracle中的VARCHAR2
,因为该数据types的行为将保持不变)。
Tom Kyte Oracle副总裁:
零长度varchar被视为NULL。
''不被视为NULL。
''当分配给一个字符(1)变成''(字符types是空白填充string)。
''当分配给varchar2(1)变成''这是一个零长度的string和一个零长度的string在Oracle中是NULL(这是很长的'')
如果您像早期的开发人员那样想到Oracle,那么我怀疑这样做会更有意义 – 作为数据input系统的后端。 数据库中的每个字段都以一种数据input操作员在其屏幕上看到的forms对应于一个字段。 如果操作员没有在字段中input任何内容,无论是“出生date”还是“地址”,那么该字段的数据是“未知的”。 运营商没有办法指出某个人的地址真的是一个空string,反正也没有什么意义。
Oracle文档通知开发人员这个问题,至less可以回溯到第7版。
Oracleselect用“不可能的价值”技术来表示NULLS。 例如,数字位置的NULL将被存储为“零 – 零”,这是一个不可能的值。 由计算得到的任何负零将在存储之前转换为正零。
Oracle也错误地select将长度为零的VARCHARstring(空string)视为一个不可能的值,并且是表示NULL的合适select。 事实certificate,空string远不是不可能的值。 甚至是string连接操作下的身份!
Oracle文档警告数据库devise人员和开发人员,Oracle的某些未来版本可能会破坏空string与NULL之间的关联,并破坏依赖于该关联的任何代码。
除了不可能的值外,还有一些标记NULLS的技术,但是Oracle并没有使用它们。
(我使用上面的“位置”一词来表示一行和一列的交集。)
空string与NULL相同,只是因为它与“两个(空string和null)”不同的情况相比,它的“较小的邪恶”。
在NULL和空string不同的语言中,必须始终检查两个条件。
因为不将它视为NULL也不是特别有用。
如果您在Oracle的这个区域犯了一个错误,您通常会马上注意到。 然而,在SQL服务器,它似乎工作,只有当有人input一个空string而不是NULL(也许从.net客户端库,其中null与“”不同,但你通常对待他们相同)。
我不是说甲骨文是对的,但在我看来,这两种方式都差不多。
据官方11g文件
Oracle数据库目前将长度为零的字符值视为null。 但是,在将来的版本中,这可能不会继续,Oraclebuild议您不要将空string视为空值。
可能的原因
-
val IS NOT NULL
比val != ''
更可读val != ''
- 不需要检查两个条件
val != '' and val IS NOT NULL
书中的例子
set serveroutput on; DECLARE empty_varchar2 VARCHAR2(10) := ''; empty_char CHAR(10) := ''; BEGIN IF empty_varchar2 IS NULL THEN DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL'); END IF; IF '' IS NULL THEN DBMS_OUTPUT.PUT_LINE(''''' is NULL'); END IF; IF empty_char IS NULL THEN DBMS_OUTPUT.PUT_LINE('empty_char is NULL'); ELSIF empty_char IS NOT NULL THEN DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL'); END IF; END;
首先,Oracle和Oracle的空string和空string并不总是一样的。 根据定义,空string是不包含字符的string。 这完全不是一个空。 根据定义,NULL是没有数据的。
在五六年前,空string被null处理与Oracle不同。 虽然,像null,空string等于一切,不同于一切(我认为是罚款空,但完全错误的空string),至less长度(空string)将返回0,因为它应该因为空string是一串零长度。
目前在Oracle中,length(null)返回null,我猜是可以的,但length(null string)也返回null,这是完全错误的。
我不明白他们为什么决定开始对待这两个不同的“价值观”。 他们意味着不同的事情,程序员应该有能力以不同的方式行事。 他们改变了方法的事实告诉我,他们真的不知道如何处理这些价值观。
事实上,我在处理Oracle时遇到了困难,包括无效的date时间值(不能被打印,转换或者任何东西,只是用DUMP()函数来查看),它们被允许插入到数据库中,显然是通过一些越野车客户端版本作为二进制列! 为了保护数据库的完整性!
Oracle处理NULL链接:
http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/
http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html