发表于: 2006.12.29 20:25
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/245697
---------------------------------------------------------------
最近在论坛上经常看到,很多人提出和NULL有关的问题。NULL其实是数据库中特有的类型,Oracle中很多容易出现的错误都是和NULL有关的。
打算简单的总结一下NULL的相关知识。
这一篇描述NULL的字符串表示格式’’。
Oracle中的NULL(一):http://yangtingkun.itpub.net/post/468/244434
Oracle中的NULL(二):http://yangtingkun.itpub.net/post/468/245107
Oracle中的NULL(三):http://yangtingkun.itpub.net/post/468/245259
发现很多人对空字符串’’不是很清楚,这里简单总结一下。
以前我总说空字符串’’等价于NULL,但是有些人喜欢钻牛角尖,所以我改一下说法,空字符串’’是NULL的字符类型的表现格式。
也许有人会认为,NULL就是NULL,本身没有类型的一说,但是我认为,NULL还是有类型的,只不过不同类型的NULL都用相同的关键字NULL来表示。而且,NULL本身也可以转化为任意类型的数据,因此给人的感觉是NULL没有数据类型。
其实NULL不但有数据类型,还有默认的数据类型,那就是字符类型。至于这个答案是如何推断出来的,请看:http://yangtingkun.itpub.net/post/468/50132
不过上面说的这个默认的数据类型是在极限的情况下测试出来的,如果只是给出一个NULL,那么它是可以代表任意的类型的。
证明空字符串就是NULL是很容易的:
SQL> SELECT 1 FROM DUAL WHERE '' = '';
未选定行
SQL> SELECT 1 FROM DUAL WHERE '' IS NULL;
1
----------
1
SQL> SELECT DUMP(''), DUMP(NULL) FROM DUAL;
DUMP DUMP
---- ----
NULL NULL
上面三个SQL语句,任意一个都足以证明空字符串’’就是NULL。
有些人可能会说,既然’’就是NULL,为什么不能进行IS ’’的判断呢?
SQL> SELECT 1 FROM DUAL WHERE '' IS '';
SELECT 1 FROM DUAL WHERE '' IS ''
*第 1 行出现错误:
ORA-00908: 缺失 NULL 关键字
其实从上面的错误信息就可以看到答案。原因就是IS NULL是Oracle的语法,在Oracle运行的时刻’’是NULL,但是现在Oracle还没有运行这句SQL,就由于语法不正确被SQL分析器挡住了。Oracle的语法并不包含IS ’’的写法,所以,这一点并不能称为’’不是NULL的理由。
那么我为什么还要说’’是NULL的字符表示形式呢?因为’’和NULL还确实不完全一样,对于NULL来说,它表示了各种数据类型的NULL值。而对于空字符串’’来说,虽然它也具有NULL的可以任意转化为其他任何数据类型的特点,但是无论是从形式上还是从本质上它都表现出了字符类型的特点。
下面通过一个例子来证明’’本质是字符类型的NULL。
SQL> CREATE OR REPLACE PACKAGE P_TEST_NULL AS
2 FUNCTION F_RETURN (P_IN IN NUMBER) RETURN VARCHAR2;
3 FUNCTION F_RETURN (P_IN IN VARCHAR2) RETURN VARCHAR2;
4 END;
5 /
程序包已创建。
SQL> CREATE OR REPLACE PACKAGE BODY P_TEST_NULL AS
2
3 FUNCTION F_RETURN (P_IN IN NUMBER) RETURN VARCHAR2 AS
4 BEGIN
5 RETURN 'NUMBER';
6 END;
7
8 FUNCTION F_RETURN (P_IN IN VARCHAR2) RETURN VARCHAR2 AS
9 BEGIN
10 RETURN 'VARCHAR2';
11 END;
12
13 END;
14 /
程序包体已创建。
SQL> SELECT P_TEST_NULL.F_RETURN(3) FROM DUAL;
P_TEST_NULL.F_RETURN(3)
------------------------------------------------------------
NUMBER
SQL> SELECT P_TEST_NULL.F_RETURN('3') FROM DUAL;
P_TEST_NULL.F_RETURN('3')
------------------------------------------------------------
VARCHAR2
SQL> SELECT P_TEST_NULL.F_RETURN('') FROM DUAL;
P_TEST_NULL.F_RETURN('')
------------------------------------------------------------
VARCHAR2
SQL> SELECT P_TEST_NULL.F_RETURN(NULL) FROM DUAL;
SELECT P_TEST_NULL.F_RETURN(NULL) FROM DUAL
*第 1 行出现错误:
ORA-06553: PLS-307: 有太多的 'F_RETURN' 声明与此次调用相匹配
从这一点上可以看出’’实际上已经具备了数据类型。所以我将’’表述为空字符串是NULL的字符类型表现形式。











