为什么oracle9i将空字符串视为null?

b1uwtaje  于 2021-07-29  发布在  Java
关注(0)|答案(10)|浏览(435)

我知道它确实考虑到了 ' 作为 NULL ,但这并不能告诉我为什么会这样。据我所知,sql规范 ' 不等于 NULL --一个是有效的数据,另一个是表示没有相同的信息。
请随意猜测,但如果是这样请注明。如果有任何来自甲骨文的人可以对此发表评论,那就太棒了!

vyu0f0g1

vyu0f0g11#

我相信答案是甲骨文非常非常古老。
早在sql标准出现之前,oracle就做出了一个设计决策,在sql中使用空字符串 VARCHAR / VARCHAR2 列为 NULL 而且只有一种空的感觉(有关系理论家会区分从未被提示的数据、存在答案但用户不知道的数据、没有答案的数据等等,所有这些都构成了某种空的感觉 NULL ).
当sql标准出现并同意 NULL 空字符串是不同的实体,已经有oracle用户的代码假定两者是等价的。因此,oracle基本上只能选择破坏现有代码、违反sql标准,或者引入某种初始化参数,这些参数可能会改变大量查询的功能。违反sql标准(imho)是这三个选项中破坏性最小的。
甲骨文留下了一个可能性 VARCHAR 数据类型将在未来的版本中更改,以符合sql标准(这就是为什么每个人都使用sql) VARCHAR2 在oracle中,因为该数据类型的行为保证在以后保持不变)。

mspsb9vt

mspsb9vt2#

tom kyte甲骨文副总裁:
长度为零的varchar被视为null。
“”未被视为null。
当分配给字符(1)时,“”变为“”(字符类型是空白填充字符串)。
当赋给varchar2(1)时,“”变为“”这是一个零长度字符串,而在oracle中零长度字符串为null(它不是长的“”)

vmdwslir

vmdwslir3#

我怀疑,如果你像早期开发人员可能做的那样考虑oracle,这会更有意义——作为数据输入系统的荣耀后端。数据库中的每个字段都对应于数据输入操作员在屏幕上看到的表单中的一个字段。如果操作员没有在字段中键入任何内容,不管是“出生日期”还是“地址”,那么该字段的数据就是“未知”。运算符无法表示某人的地址实际上是一个空字符串,这也没有多大意义。

qnzebej0

qnzebej04#

oracle文档提醒开发人员注意这个问题,至少可以追溯到版本7。
oracle选择用“不可能值”技术表示空值。例如,数字位置中的null将存储为“负零”,这是一个不可能的值。任何由计算产生的负零将在存储之前转换为正零。
oracle还错误地认为长度为零的varchar字符串(空字符串)是不可能的值,是表示null的合适选择。事实证明,空字符串远不是一个不可能的值。它甚至是字符串串联操作下的标识!
oracle文档警告数据库设计人员和开发人员,oracle的某些未来版本可能会破坏空字符串和null之间的关联,并破坏依赖于该关联的任何代码。
除了不可能的值之外,还有一些技术可以标记null,但是oracle没有使用它们。
(我用上面的“位置”一词来表示行和列的交叉点。)

b5buobof

b5buobof5#

空字符串与空字符串相同,只是因为与两者(空字符串和空字符串)不相同的情况相比,空字符串是“较小的邪恶”。
在空字符串和空字符串不相同的语言中,必须同时检查这两个条件。

5sxhfpxr

5sxhfpxr6#

根据官方11g文件
oracle数据库当前将长度为零的字符值视为null。但是,这在将来的版本中可能不再适用,oracle建议不要将空字符串视为null。
可能的原因 val IS NOT NULL 可读性比 val != '' 不需要同时检查这两种情况 val != '' and val IS NOT NULL

kx7yvsdv

kx7yvsdv7#

书中的例子

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;
d4so4syb

d4so4syb8#

因为不把它当作null也不是特别有用。
如果你在甲骨文这方面犯了错误,你通常会马上注意到。但是,在sql server中,它似乎可以工作,只有当有人输入空字符串而不是null时,问题才会出现(可能是从.net客户机库输入的,其中null与“”不同,但您通常会对它们进行相同的处理)。
我并不是说甲骨文是对的,但在我看来,这两种方法几乎都是同样糟糕的。

bnlyeluc

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

6ioyuze2

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,这是完全错误的。
我不明白他们为什么决定对这两个不同的“价值观”一视同仁。它们意味着不同的事情,程序员应该有能力以不同的方式处理每一件事情。他们改变了他们的方法论,这一事实告诉我,他们真的不知道应该如何对待这些价值观。

相关问题