学习与编程版
Oracle中空值的应用河北省统计局 贾书民____在数据库中,空值(NULL)用来表示实际值未知或无意义的情况。在一个表中,如果一行中的某列没有值,那么就称它为空值。任何数据类型的列,只要没有使用非空(NOT NUL L)或主键(PRIMARY KEY)完整性限制,都可以出现空值。在实际应用中,如果忽略空值的存在,将会造成很多麻烦。例如,在下面的雇员表(EMP)中,雇员名(ENAME)为KING的行,因为 KING为最高官员(PRESIDENT),他没有主管(MGR),所以其MGR为空值。
表1 ____本文将以上述EMP表为例,具体讨论一下空值在日常应用中所具有的一些特性。 ____空值的生成及特点 ____1. 空值的生成 ____如果一列没有非空(NOT NULL)完整性限制,那么其缺省的值为空值,即如果插入一行时未指定该列的值,则其值为空值。 ____使用SQL语句INSERT插入行,凡未涉及到的列,其值为空值;涉及到的列,如果其值确实为空值,插入时可以用NULL来表示(对于字符型的列,也可以用‘’来表示)。 ____例:插入一行,其EMPNO为1、ENAME为‘JIA’、SAL为10000、job和comm为空值: ____SQL>insert into emp(empno,ename,job,sal,comm) values(1,‘JIA’,NULL,1000 ,NULL); ____使用SQL语句UPDATE来修改数据,空值可用NULL来表示,例: ____SQL>update emp set ename=NULL,sal=NULL where empno=1; ____2. 空值的特点 ____空值具有以下特点: ____· 等价于没有任何值; ____· 与 0、空字符串或空格不同; ____· 在where条件中, Oracle认为结果为NULL的条件为FALSE,带有这样条件的select 语句不返回行,并且不返回错误信息,但NULL和FALSE是不同的; ____· 排序时比其他数据都大; ____· 空值不能被索引。 ____空值的测试 ____因为空值表示缺少数据,所以空值和其它值没有可比性,即不能用等于、不等于、大于或小于和其它数值比较,当然也包括空值本身(但是在decode中例外,两个空值被认为是等价)。测试空值只能用比较操作符IS NULL 和IS NOT NULL。如果使用带有其它比较操作符的条件表达式,并且其结果依赖于空值,那么其结果必定是NULL。在where条件中,Or acle认为结果为NULL的条件为FALSE,带有这样条件的select语句不返回行,也不返回错误信息。例如查询EMP表中MGR为NULL的行:
表2 ____第1、2句写法不妥,WHERE条件结果为NULL,不返回行。第三句正确,返回MGR为空值的行。 ____空值和操作符 ____1. 空值和逻辑操作符
表3 ____可以看到,在真值表中,除NULL AND FALSE 结果为FALSE、NULL OR TRUE结果为TRUE 以外,其它结果均为NULL。 ____虽然在where条件中,Oracle认为结果为NULL的where条件为FALSE,但在条件表达式中 NULL不同于FALSE。例如在NOT( NULL AND FALSE )和NOT ( NULL AND NULL )中,前者结果为 TRUE,而后者结果为NULL。 ____下面举例说明空值和逻辑操作符的用法:
表4 ____第一个Select语句,条件"not comm=null and comm!=0"等价于NULL AND COMM!=0。对于任意一行,如果COMM为不等于0的数值,条件等价于NULL AND TRUE,结果为NULL;如果 COMM等于0,条件等价于NULL AND FALSE,结果为FALSE。所以,最终结果不返回行。 ____第二个Select语句的条件为第一个Select语句条件的"非"(NOT),对于任意一行,如果 COMM为不等于0的数值,条件等价于NOT NULL,结果为NULL;如果COMM等于0,条件等价于NO T FALSE,结果为TRUE。所以,最终结果返回行COMM等于0的行。 ____2. 空值和比较操作符 ____(1) IS [NOT] NULL:是用来测试空值的唯一操作符。 ____(2) =、!=、>=、<=、>、< SQL>select ename,sal,comm from emp where sal>co mm; ____ENAME SAL COMM ____--------------------------------------------- ____ALLEN 1600 300 ____WARD 1250 500 ____TURNER 1500 0 ____sal或comm为空值的行,sal>comm比较结果为NULL,所以凡是sal或comm为空值的行都没有返回。 ____(3) IN和NOT IN操作符 SQL>select ename,mgr from emp where mgr in (7902,NU LL); ____ENAME MGR ____SMITH 7902 ____在上述语句中,条件"mgr in (7902,NULL)"等价于mgr=7902 or mgr=NULL。对于表E MP中的任意一行,如果mgr为NULL,则上述条件等价于NULL OR NULL,即为NULL;如果mgr为不等于7902的数值,则上述条件等价于FALSE OR NULL,即为NULL;如果mgr等于7902,则上述条件等价于TRUE OR NULL,即为TRUE。所以,最终结果能返回mgr等于7902的行。 ____(4) any,some SQL>select ename,sal from emp where sal> any(3000,null); ____ENAME SAL ____KING 5000 ____条件"sal> any(3000,null)"等价于sal>3000 or sal>null,类似前述(3),最终结果返回所有sal>3000的行。 ____(5) All SQL>select ename,sal from emp where sal> all(3000,null); ____no rows selected ____条件"sal> all(3000,null)"等价于sal>3000 and sal>null, 结果只能为NULL或FA LSE,所以不返回行。 ____(6) (not)between SQL>select ename,sal from emp where sal between null and 3000; ____no rows selected ____条件"sal between null and 3000"等价于sal>=null and sal<=3000, 结果只能为 NULL或FALSE,所以不返回行。 ____下表为比较操作符和空值的小结:
表5 ____3. 空值和算术、字符操作符 ____(1) 算术操作符:空值不等价于0,任何含有空值的算术表达式其运算结果都为空值, 例如空值加10为空值。 ____(2) 字符操作符||:因为Oracle目前处理零个字符值的方法与处理空值的方法相同( 以后的版本中不一定仍然如此),所以对于||,空值等价于零个字符值。 ____空值和函数 ____1. 空值和度量函数 ____对于度量函数,如果给定的参数为空值,则其(NVL、TRANSLATE除外)返回值为空值。如本文所述例子中的ABS(COMM),如果COMM为空值,ABS(COMM)为空值。 ____2. 空值和组函数 ____组函数忽略空值。在实际应用中,根据需要可利用nvl函数用零代替空值。例如:
表6 ____第一个SELECT语句忽略COMM为空值的行,第二个SELECT语句使用NVL函数统计了所有的COMM,所以它们统计的个数、平均值都不相同。 ____另外需要注意的是,在利用组函数进行数据处理时,不同的写法具有不同的含义,在实际应用中应灵活掌握。例如:
表7 ____可以看到SUM(SAL+COMM)、SUM(SAL)+SUM(COMM)、 SUM(NVL(SAL,0)+NVL(COMM,0))的区别:SUM(SAL+COMM)为先加然后计算各行的和,如果SAL、COMM中有一个为NULL,则该行忽略不计;SUM(SAL)+SUM(COMM)为先计算各行的合计然后再加,SAL、COMM中的NULL都忽略不计,但如果 SUM(SAL)、SUM(COMM)二者的结果之中有一个为NULL,则二者之和为NULL;在S UM(NVL(SAL,0)+NVL(COMM,0))里,SAL、COMM中的NULL按0处理。 ____空值的其它特性 ____1. 空值在排序时大于任何值。 ____2. 空值不能被索引。虽然在某列上建立了索引,但是对该列的空值查询来说,因为空值没有被索引,所以不能改善查询的效率。 ____另外正是因为空值不被索引,所以可在含有空值的列上建立唯一性索引(UNIQUE IND EX)。例如,可以在EMP表的COMM列上建立唯一性索引: ____SQL> create unique index emp_comm on emp(comm); ____Index created. |