在 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);
语句 | 结果 |
---|---|
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 的发生在所有表达式上下文中收到它的全局作用域。
CREATE TABLE newtable ( null int ); SELECT null, null::int FROM newtable;
CREATE TABLE 语句是有效的,因为列标识符具有限定到表定义的引用的作用域;仅可在表的作用域内访问它们。
SELECT newtable.null, null::int FROM newtable;
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。
-947 Declaration of an SPL variable named 'null' conflicts with SQL NULL value.
在 ESQL/C 中,如果有 SELECT 语句会返回 NULL 值的可能性,则您应使用指示符变量。