NULL 关键字

在您可指定值的大部分上下文中,NULL 关键字是有效的。然而,它指定的内容没有任何值(或未知的或遗失的值)。
NULL 关键字

在 SQL 内,关键字 NULL 是访问 NULL 值的唯一语法机制。NULL 不等同于零,也不等同于任何特定的值。在升序的 ORDER BY 操作中,NULL 值排在任何非 NULL 值之前;在降序排序中,NULL 值跟在任何非 NULL 值之后。在 GROUP BY 操作中,所有 NULL 值都组在一起。(如果它们包括遗失的值或未知的值,则这样的分组可能在逻辑上是各种各样的。)

在表达式的语法上下文中,关键字 NULL 是全局的符号,意味着它的引用作用域是全局的。

不论是内建的还是用户定义的,每种数据类型都可代表 NULL 值。GBase 8s 支持在 projection 列表中的强制转型表达式。这意味着用户可写 NULL::datatype 形式的表达式,其中的 datatype 是数据库服务器已知的任何数据类型。

GBase 8s 支持在通用的表达式中的 typed NULL 关键字。在这些情境下的单独的 NULL 导致 -201 语法错误。因此,如果定义 null 为列名称或进程名称,在必须以表别名引用它。否则,它返回 -201 语法错误。在下列示例和结果中总结该行为:

create table tab1 (a int, null int);
        create table tab2 (a int, b int);
表 1. NULL 行为
语句 结果
select null from tab1 where a = 1
-201 语法错误
select * from tab1 where null = a
-201 语法错误
select * from tab1 where tab1.null = a
有效的语法
select * from tab1 where a = null
-201 语法错误
select * from tab2 where a = null
-201 语法错误
select * from tab2 where null = a
-201 语法错误
select * from tab2 where null = a
-201 语法错误
select NULL::int from tab1
有效的语法
select NULL::int from tab1
有效的语法
select 1 + NULL::int from tab1
有效的语法
select 1 + NULL::int from tab2
有效的语法
select NULL::int + 1 from tab1
有效的语法

GBase 8s 禁止重新定义 NULL,因为允许这样定义会限制 NULL 关键字的全局作用域。为此,任何限制全局作用域或重新定义关键字 NULL 的作用域的机制都会在语法上禁用涉及 NULL 值的任何强制转型表达式。您必须确保关键字 NULL 的发生在所有表达式上下文中收到它的全局作用域。

例如,请考虑下列 SQL 代码:
CREATE TABLE newtable
        (
        null int
        );
        
        SELECT null, null::int FROM newtable;

CREATE TABLE 语句是有效的,因为列标识符具有限定到表定义的引用的作用域;仅可在表的作用域内访问它们。

然而,在该示例中的 SELECT 语句引起一些语法的多义性。出现在 projection 列表中的标识符 null 引用全局的关键字 NULL 吗?它引用在 CREATE TABLE 语句中声明了的列标识符 null 吗?
  • 如果将标识符 null 解释作为列名称,则带有 NULL 关键字的强制转型表达式的全局作用域将会受限。
  • 如果将标识符 null 解释作为 NULL 关键字,则 SELECT 语句必须为 null 的发生生成语法错误,因为 NULL 关键字仅可作为强制转型表达式出现在 projection 列表中。
下列形式的 SELECT 语句是有效的,因为以表名称限定 newtable 的 NULL 列:
SELECT newtable.null, null::int FROM newtable;
在有名为 null 的变量的 SPL 例程的上下文中,会出现更多语法的多义性。示例如下:
CREATE FUNCTION nulltest() RETURNING INT;
          DEFINE a INT;
          DEFINE null INT;
          DEFINE b INT;
          LET a = 5;
          LET null = 7;
          LET b = null;
          RETURN b;
          END FUNCTION;
          
          EXECUTE FUNCTION nulltest();

当在 DB-Access 中执行前面的函数时,在 LET 语句的表达式中,创建标识符 null 作为关键字 NULL。该函数返回 NULL 值,而不是 7。

使用 null 作为 SPL 例程的变量会限制在 SPL 例程体中对 NULL 值的使用。因此,前面的 SPL 代码是无效的,并导致 GBase 8s 返回下列错误:
-947   Declaration of an SPL variable named 'null' conflicts
          with SQL NULL value.

在 ESQL/C 中,如果有 SELECT 语句会返回 NULL 值的可能性,则您应使用指示符变量。