我知道它确实将q表示为NULL,但这并不能告诉我为什么会这样。据我了解的SQL规范,'\'与NULL不同-一个是有效的数据,另一个表明缺少相同的信息。

随意推测,但是请指出是否如此。如果有Oracle的任何人可以对此发表评论,那就太好了!

评论

随意推测?以某种方式,我认为这不会为您提供最大的答案。.

我想不是,但是我不确定这个问题是否有确定性,所以我想我会把门打开。到目前为止看来似乎还可以。

docs.oracle.com/database/121/SQLRF / ...

相关:dba.stackexchange.com/q/49744/56961

#1 楼

我相信答案是Oracle非常非常古老。

在过去有SQL标准之前,Oracle做出了设计决策,即VARCHAR / VARCHAR2列中的空字符串是NULL,并且仅有一种NULL感觉(有一些相关的理论家会区分从未提示过的数据,存在答案但用户不知道的数据,没有答案的数据等)。在某种程度上理解了NULL)。当SQL标准问世并同意NULL和空字符串是不同的实体时,已经有Oracle用户使用了假定两者相等的代码。因此,Oracle基本上可以选择破坏现有代码,违反SQL标准或引入某种初始化参数的选择,这些参数可能会更改大量查询的功能。在这三个选项中,违反SQL标准(IMHO)的破坏性最小。

Oracle保留了VARCHAR数据类型在将来的版本中更改以遵守SQL标准的可能性(即为什么每个人都在Oracle中使用VARCHAR2,因为保证该数据类型的行为今后保持不变)。

#2 楼

Oracle副总裁Tom Kyte:


零长度的varchar被视为
''不被视为NULL。 >
''分配给char(1)时变为
''(字符类型为空白填充
字符串)。

''当分配给varchar2(1)
时成为'',它是零长度的字符串,而零长度的字符串在Oracle中是NULL(它不再是'')


评论


哇,汤姆很。鉴于这些问题与SQL92的巨大差异有关,您可能会认为他对它的影响不那么大……尽管他可能厌倦了回答。

–克里斯·R
08-10-15在3:10

关于汤姆,最好的事情是您得到一个明确的答案,该答案准确地说出了他的想法。在人们使用文字说“问汤姆”的地方查找一些评论

–克里斯·吉尔(Chris Gill)
09年8月27日在12:17

但是,如果第二行更改为”并不总是视为NULL,则会更精确。

–超立方体ᵀᴹ
2011年7月5日在7:48



@ypercube通过更改Tom实际使用的单词,报价不会变得更加精确。如果您认为汤姆的措辞令人困惑,嗯。也许。我认为他是正确的。当''被隐式转换为VARCHAR2时,会出现最令人困惑的情况,例如cast(''as char(1))为null,这是……令人惊讶的TRUE

–sehe
13年7月19日在15:17



@sehe对我来说令人困惑的是从对偶中选择1,其中(''为null)

–哑光怪胎
13年8月22日在15:58

#3 楼

我怀疑如果您像以前的开发人员那样来考虑Oracle,将其作为数据输入系统的光荣后端,那会更有意义。数据库中的每个字段都对应于一个数据输入操作员在其屏幕上看到的格式的字段。如果操作员未在字段中键入任何内容,无论是“出生日期”还是“地址”,则该字段的数据均为“未知”。操作员无法指出某人的地址确实是一个空字符串,无论如何这实际上没有多大意义。

评论


仅当您假设数据输入系统中的每个字段都是必填字段时,这才有意义。对非必填字段的非回答(例如“狗的名字”)是有效的,因此空字符串仍然具有与NULL不同的用途。即使有了这个假设,我仍然怀疑早期的开发人员是否将Oracle视为“数据输入系统的光荣后端”,因此我不确定这个答案是否完全有意义。

–讨厌
15年11月13日在19:07



#4 楼

Oracle文档警告开发人员注意此问题,至少可以追溯到版本7。

Oracle选择通过“不可能的值”技术来表示NULL。例如,数字位置的NULL将存储为“减零”,这是不可能的值。计算产生的任何负零将在存储之前转换为正零。

Oracle还错误地选择将长度为零的VARCHAR字符串(空字符串)视为不可能的值,并且是表示NULL的合适选择。事实证明,空字符串远非不可能的值。甚至在字符串串联操作下的身份!

Oracle文档警告数据库设计人员和开发人员,Oracle的某些将来版本可能会破坏空字符串和NULL之间的这种关联,并破坏任何依赖于该关联的代码。

除了不可能的值外,还有标记空值的技术,但是Oracle没有使用它们。

(我在上面使用“位置”一词来表示行与列的交集。)

评论


Oracle文档警告数据库设计人员和开发人员,Oracle的某些将来版本可能会破坏空字符串和NULL之间的这种关联,并破坏依赖于该关联的任何代码–您能否提供此语句的参考?

–彼得·多布罗格斯特(Piotr Dobrogost)
18-10-15在20:44

docs.oracle.com/cd/B19306_01/server.102/b14200 / ...

– Walter Mitty
18-10-16在0:29

#5 楼

空字符串与NULL相同,只是因为与两个(空字符串和null)不同时的情况相比,它的“较小危害”。

在NULL和空字符串不同的语言中,必须始终检查这两个条件。

评论


只需在您的列上设置not null约束,然后仅检查空字符串即可。

– Egor Skriptunoff
2013年6月29日23:27

检查这两个条件很简单:在具有空字符串的ANSI行为的数据库上,仅当该字段不为NULL并且不为空时,WHERE Field <>''才返回true。

–user565869
2014年7月9日14:24

#6 楼

根据11g官方文档,


Oracle数据库当前将长度为零的字符值视为空值。但是,在将来的发行版中,情况可能不会继续如此,并且Oracle建议您不要将空字符串与null相同。


可能的原因



val IS NOT NULLval != ''更易读
无需检查两个条件val != '' and val IS NOT NULL



评论


在完全符合ANSI的数据库中,您不必检查这两种情况。 val <>''已排除NULL。也许您的意思是val =''或val IS NULL。但是不比较为NULL的空字符串很有用!

– ErikE
16-2-3在16:02



我同意比较部分。

–分类
19年6月26日在5:44

#7 楼

书中的示例

   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;


#8 楼

因为也不将其视为NULL也没有特别的帮助。

如果您在Oracle的这一方面犯了错误,通常会立即注意到。但是,在SQL Server中,它似乎可以正常工作,并且仅当有人输入空字符串而不是NULL时,问题才会出现(也许来自.net客户端库,其中null与“”不同,但通常将它们相同)。

我并不是说Oracle是正确的,但是在我看来,这两种方法几乎都同样糟糕。

评论


调试起来要容易得多。另外,如果您在屏幕上看到一个空单元格或输入,则知道数据库中的数据为空。在其他数据库中,“ <> NULL”中,您无法“看到”数据是否为null或,这会导致非常隐蔽的错误。 ''= null是最明智的选择,即使它不是标准的。

– Lucio M. Tato
13-10-18在20:02

“在其他数据库中,如果<<> NULL,则不能“看到”数据是否为空或“”” =>通常,数据库工具显示的NULL与空字符串的显示方式不同。实际上,甚至Oracle SQL Developer都将NULL显示为“(null)”。我想这是为了将NULL与空白区分开来,但这与NULL和空字符串之间的区别无关。

–Didier L
2014年9月23日14:18在

#9 楼

确实,我在处理Oracle时没有任何困难,包括无效的日期时间值(无法打印,转换或其他任何东西,只能通过DUMP()函数查看),这些值显然可以通过某些错误插入数据库中。客户端版本作为二进制列!保护数据库完整性非常重要!

Oracle处理NULL链接:

http://digitalbush.com/2007/10/27/oracle-9i-null-behavior /

http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html

评论


无效的数据时间值?不确定那是什么意思。您是否已在此处发布此问题?

–马克·布雷迪
08-10-15在15:17

这个问题是在堆栈溢出之前发生的-我从Oracle论坛上没有得到有用的信息,并且创建了一种解决方法-我将跟踪我的笔记并在此处发布。

–Cade Roux
08-10-15在15:56

在此处发布详细信息作为问题。

–Cade Roux
08-10-15在16:13

#10 楼

首先,Oracle并不总是将null和null字符串视为相同。根据定义,空字符串是不包含任何字符的字符串。这与null完全不同。顾名思义,NULL是指没有数据。

大约五六年前,Oracle将null字符串与null区别对待。虽然像null一样,null字符串等于所有内容,并且不同于所有内容(我认为对null很好,但对于null字符串则完全错误),但至少length(null string)将返回0,因为它应该为null字符串长度为零的字符串。

当前在Oracle中,length(null)返回null,我猜是可以的,但是length(null string)也返回null,这完全是错误的。

我不明白他们为什么决定开始将这两个不同的“价值”一视同仁。它们意味着不同的事物,程序员应具有以不同方式对每种事物进行操作的能力。他们改变了方法论的事实告诉我,他们真的不知道应该如何对待这些价值观。

评论


区分“空字符串”和NULL值所需的引用。在除Oracle之外的任何数据库中,VARCHAR字段可以有一个值(零个或多个字符)或没有值(NULL),即句点。

–user565869
2014年7月9日14:27

从2011年开始的“五六年前”将落在10g的时间范围内(2003年发布的10.1,2005年发布的10.2)。 10g绝对不会在处理null时引入任何全局更改,并且NULL与null值的字符串之间从来没有任何区别,这种区别是没有意义的。恐怕这个答案是一个完整的幻想。

–威廉·罗伯逊
18年7月21日在10:34