为什么Oracle 9i将空字符串视为NULL?
题
我知道确实考虑' '作为 NULL
,但这并没有太多告诉我为什么就是这种情况。据我了解SQL规范,' '与 NULL
不同 - 一个是有效的数据,另一个是缺少相同的信息。
随意推测,但请说明是否属实。如果甲骨文的任何人都可以评论它,那就太棒了!
解决方案
我相信答案是甲骨文非常非常老。
回到有过SQL标准的前几天,Oracle做出了设计决定, VARCHAR
/ VARCHAR2
列中的空字符串是 NULL
并且只有一种NULL感(有关系理论家可以区分从未提示过的数据,答案存在但用户不知道的数据,没有答案的数据等等。其中构成了 NULL
)的一些意义。
当SQL标准出现并同意 NULL
并且空字符串是不同的实体时,已经有Oracle用户拥有代码,假设这两者是等效的。因此Oracle基本上选择了破坏现有代码,违反SQL标准或引入某种初始化参数来改变潜在大量查询的功能。违反SQL标准(恕我直言)是这三个选项中破坏性最小的。
Oracle已经保留了 VARCHAR
数据类型在未来版本中将更改以遵守SQL标准的可能性(这就是为什么每个人都在Oracle中使用 VARCHAR2
的原因)保证数据类型的行为在未来保持不变。
其他提示
Tom Kyte Oracle副总裁:
ZERO长度varchar被视为 NULL。
''不被视为NULL。
当分配给char(1)时,''变为 ''(字符类型为空白填充 字符串)。
分配给varchar2(1)时'' 成为''这是一个零长度 字符串和零长度字符串 Oracle中的NULL(不久')
我怀疑如果你像早期的开发人员那样想到Oracle,这会更有意义 - 作为数据输入系统的美化后端。数据库中的每个字段对应于数据输入操作员在其屏幕上看到的表单中的字段。如果操作员没有在字段中键入任何内容,那么这是否是“生日”。或“地址”或然后该字段的数据是“未知的”。对于操作员来说,没有办法表明某人的地址确实是一个空字符串,而且这无论如何都没有多大意义。
Oracle文档提醒开发人员注意这个问题,至少可以追溯到版本7。
Oracle选择以“不可能的价值”来代表NULLS。技术。例如,数字位置中的NULL将被存储为“零 - 零”,这是一个不可能的值。计算产生的任何负零将在存储之前转换为正零。
Oracle错误地选择将长度为零的VARCHAR字符串(空字符串)视为不可能的值,并且是表示NULL的合适选择。事实证明,空字符串远非一个不可能的值。它甚至是字符串连接操作下的身份!
Oracle文档警告数据库设计人员和开发人员可能会使用Oracle的未来版本 打破空字符串和NULL之间的这种关联,并打破依赖于该关联的任何代码。
除了不可能的值之外,还有一些技术可以标记NULLS,但Oracle并没有使用它们。
(我在上面使用“location”一词表示行和列的交集。)
空字符串与NULL相同只是因为它的“较小的邪恶”当与两个(空字符串和null)不相同的情况相比时。
在NULL和空字符串不相同的语言中,必须始终检查两个条件。
Oracle数据库当前将长度为零的字符值视为null。但是,在将来的版本中可能不会继续这样,Oracle建议您不要将空字符串视为空值。
可能的原因
-
val IS NOT NULL
比val!=''
更具可读性
- 无需检查两个条件
val!=''和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;
因为不将它视为NULL也不是特别有用。
如果您在Oracle上的这个区域出错,您通常会立即注意到。但是,在SQL服务器中,它似乎可以正常工作,并且只有当有人输入空字符串而不是NULL(可能来自.net客户端库,其中null与“&”不同时)才会出现问题,但是您通常会对它们进行处理同样的。)
我不是说甲骨文是正确的,但在我看来,两种方式都差不多。
事实上,我只有处理Oracle的困难,包括无效的日期时间值(无法打印,转换或任何东西,只需用DUMP()函数查看)允许到被插入到数据库中,显然是通过客户端的一些错误版本作为二进制列!这么多是为了保护数据库的完整性!
Oracle处理NULLs链接:
http://digitalbush.com/2007/10/ 27 / ORACLE-9I-空行为/
http://jeffkemponoracle.com/2006/02/empty -string-安道尔-null.html
首先,Oracle和null并不总是将null和null字符串视为相同。根据定义,空字符串是不包含字符的字符串。这与null完全不同。根据定义,NULL是缺少数据的。
五六年前,Oracle对null字符串的处理方式与null不同。虽然像null一样,null字符串等于所有内容并且与所有内容不同(我认为对于null很好,但对于null字符串完全是WRONG),至少length(null字符串)将返回0,因为它应该返回0,因为它应该是null字符串是一个零长度的字符串。
目前在Oracle中,length(null)返回null,我猜是O.K.,但length(null string)也返回null,这完全是错误的。
我不明白为什么他们决定开始处理这两个不同的“价值观”。相同。它们意味着不同的东西,程序员应该能够以不同的方式对每个事物采取行动。事实上,他们已经改变了他们的方法论,这告诉我他们真的不知道如何处理这些价值观。