根据官方11g文件 oracle数据库当前将长度为零的字符值视为null。但是,这在将来的版本中可能不再适用,oracle建议不要将空字符串视为null。 可能的原因 val IS NOT NULL 可读性比 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;
10条答案
按热度按时间vyu0f0g11#
我相信答案是甲骨文非常非常古老。
早在sql标准出现之前,oracle就做出了一个设计决策,在sql中使用空字符串
VARCHAR
/VARCHAR2
列为NULL
而且只有一种空的感觉(有关系理论家会区分从未被提示的数据、存在答案但用户不知道的数据、没有答案的数据等等,所有这些都构成了某种空的感觉NULL
).当sql标准出现并同意
NULL
空字符串是不同的实体,已经有oracle用户的代码假定两者是等价的。因此,oracle基本上只能选择破坏现有代码、违反sql标准,或者引入某种初始化参数,这些参数可能会改变大量查询的功能。违反sql标准(imho)是这三个选项中破坏性最小的。甲骨文留下了一个可能性
VARCHAR
数据类型将在未来的版本中更改,以符合sql标准(这就是为什么每个人都使用sql)VARCHAR2
在oracle中,因为该数据类型的行为保证在以后保持不变)。mspsb9vt2#
tom kyte甲骨文副总裁:
长度为零的varchar被视为null。
“”未被视为null。
当分配给字符(1)时,“”变为“”(字符类型是空白填充字符串)。
当赋给varchar2(1)时,“”变为“”这是一个零长度字符串,而在oracle中零长度字符串为null(它不是长的“”)
vmdwslir3#
我怀疑,如果你像早期开发人员可能做的那样考虑oracle,这会更有意义——作为数据输入系统的荣耀后端。数据库中的每个字段都对应于数据输入操作员在屏幕上看到的表单中的一个字段。如果操作员没有在字段中键入任何内容,不管是“出生日期”还是“地址”,那么该字段的数据就是“未知”。运算符无法表示某人的地址实际上是一个空字符串,这也没有多大意义。
qnzebej04#
oracle文档提醒开发人员注意这个问题,至少可以追溯到版本7。
oracle选择用“不可能值”技术表示空值。例如,数字位置中的null将存储为“负零”,这是一个不可能的值。任何由计算产生的负零将在存储之前转换为正零。
oracle还错误地认为长度为零的varchar字符串(空字符串)是不可能的值,是表示null的合适选择。事实证明,空字符串远不是一个不可能的值。它甚至是字符串串联操作下的标识!
oracle文档警告数据库设计人员和开发人员,oracle的某些未来版本可能会破坏空字符串和null之间的关联,并破坏依赖于该关联的任何代码。
除了不可能的值之外,还有一些技术可以标记null,但是oracle没有使用它们。
(我用上面的“位置”一词来表示行和列的交叉点。)
b5buobof5#
空字符串与空字符串相同,只是因为与两者(空字符串和空字符串)不相同的情况相比,空字符串是“较小的邪恶”。
在空字符串和空字符串不相同的语言中,必须同时检查这两个条件。
5sxhfpxr6#
根据官方11g文件
oracle数据库当前将长度为零的字符值视为null。但是,这在将来的版本中可能不再适用,oracle建议不要将空字符串视为null。
可能的原因
val IS NOT NULL
可读性比val != ''
不需要同时检查这两种情况val != '' and val IS NOT NULL
kx7yvsdv7#
书中的例子
d4so4syb8#
因为不把它当作null也不是特别有用。
如果你在甲骨文这方面犯了错误,你通常会马上注意到。但是,在sql server中,它似乎可以工作,只有当有人输入空字符串而不是null时,问题才会出现(可能是从.net客户机库输入的,其中null与“”不同,但您通常会对它们进行相同的处理)。
我并不是说甲骨文是对的,但在我看来,这两种方法几乎都是同样糟糕的。
bnlyeluc9#
事实上,我在处理oracle时遇到了很多困难,包括无效的datetime值(无法打印、转换或其他任何东西,只需使用dump()函数查看),这些值被允许插入数据库,显然是通过一些有缺陷的客户端版本作为二进制列插入的!关于保护数据库完整性的内容太多了!
oracle处理空链接:
http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/
http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html
6ioyuze210#
首先,null和null字符串并不总是被oracle视为相同的。根据定义,空字符串是不包含字符的字符串。这与空值完全不同。根据定义,null表示没有数据。
大约五六年前,空字符串被oracle区别对待。尽管像null一样,null string等于所有内容,不同于所有内容(我认为这对于null来说是好的,但是对于null string来说是完全错误的),但至少length(null string)会返回0,因为null string是长度为零的字符串。
目前在oracle中,length(null)返回null,我想这是可以的,但是length(null string)也返回null,这是完全错误的。
我不明白他们为什么决定对这两个不同的“价值观”一视同仁。它们意味着不同的事情,程序员应该有能力以不同的方式处理每一件事情。他们改变了他们的方法论,这一事实告诉我,他们真的不知道应该如何对待这些价值观。