托尼·安德鲁斯在另一个问题中举了一个例子:
IF p_c_courtesies_cd || p_c_language_cd || v_c_name || v_c_firstname || v_c_function || p_c_phone || p_c_mobile p_c_fax || v_c_email is not null THEN -- Do something END IF;
作为Oracle COALESCE函数的巧妙替代(如果不是晦涩的话)。果然,它可以工作,如果任何参数不为null,则IF测试为true。我的问题:上述连接操作SQL-92的Oracle实现是否符合要求?包含NULL的表达式不应该计算为NULL吗?如果您不这样认为,那么为什么表达式1 + NULL求值为NULL?
不,Oracle对null的处理方式是独特的,不同于其他所有人,并且与ANSI标准不一致。然而,在Oracle的辩护中,它很可能早就成立并致力于这种处理,直到有与之一致的ANSI标准为止!
这一切都始于Oracle存储带有字符计数和字符串数据的字符串。NULL由零的字符计数表示,没有后续的字符串数据- 与空字符串(’‘)完全相同。Oracle根本没有办法区分它们。
这会导致一些古怪的行为,例如这种串联情况。Oracle还具有一个LENGTH函数来返回字符串的长度,但这是以相反的方式定义的,因此LENGTH(’‘)返回NULL而不是零。所以:
LENGTH('abc') + LENGTH('') IS NULL LENGTH('abc' || '') = 3
在我看来,这违反了基本的数学原理。
当然,Oracle开发人员已经习惯了这一点,以至于我们许多人甚至看不到任何错误或奇怪的地方-实际上,有些人会认为世界其他地方是错误的,并且空字符串和NULL是 相同的事物!