ITPub博客

首页 > Linux操作系统 > Linux操作系统 > NULL的数据类型(二)

NULL的数据类型(二)

原创 Linux操作系统 作者:yangtingkun 时间:2010-08-04 23:42:24 0 删除 编辑

以前写过一篇文章,通过DECODE来确定NULL的默认数据类型,前几天在开发版发现newkid通过不同的方法得出了相同的答案。

NULL的数据类型:http://yangtingkun.itpub.net/post/468/50132

ITPUB中原贴:http://www.itpub.net/thread-1328690-1-1.html

 

NULL比较特殊,任何数据类型的空都用NULL来表示,因此NULL可以是任何数据类型。所以在一般情况下,NULL也是不会体现出具体的类型的。

不过有时候还是可以从一些特殊的情况判断出Oracle给NULL确定的默认类型。

比如newkid给出的CREATE VIEW的例子:

SQL> CREATE VIEW V_NULL AS
  2  SELECT NULL N 
  3  FROM DUAL;

视图已创建。

SQL> DESC V_NULL
 
名称                                                    是否为空? 类型
 ------------------------------------------------------- -------- --------
 N                                                                VARCHAR2

和我前一篇得出的结果是一样的,Oracle在某些情况下,会把NULL当作VARCHAR2类型来处理。

而且同时还发现几个有意思的现象:

SQL> CREATE OR REPLACE VIEW V_TEST AS
  2  SELECT SYSDATE N FROM DUAL
  3  UNION ALL
  4  SELECT NULL FROM DUAL;

视图已创建。

SQL> DESC V_TEST
 
名称                                                    是否为空? 类型
 ------------------------------------------------------- -------- --------------
 N                                                                DATE

SQL> CREATE OR REPLACE VIEW V_TEST AS
  2  SELECT SYSDATE N FROM DUAL
  3  UNION ALL
  4  SELECT '' FROM DUAL;
SELECT SYSDATE N FROM DUAL
       *
第 2 行出现错误:
ORA-01790:
表达式必须具有与对应表达式相同的数据类型

Oracle会检查UNION ALL包含的两个查询结果的数据类型是否匹配,如果不匹配就会出现上面的错误。其实在以前的文章中已经提到过,空字符串‘‘是NULL的字符类型表现形式,具体的描述可以参考:http://yangtingkun.itpub.net/post/468/245697

由于NULL可以转换为任意的类型,因此Oracle检查到NULL后,会根据另一个查询的类型来确定最终的类型,但是空字符串‘‘已经表现出了字符类型,因此和另一个查询的DATE类型不相符因此报错。

重点是下面的结果:

SQL> CREATE OR REPLACE VIEW V_TEST AS
  2  SELECT NULL N FROM DUAL
  3  UNION ALL
  4  SELECT '' FROM DUAL;

视图已创建。

SQL> DESC V_TEST
 
名称                                                    是否为空? 类型
 ------------------------------------------------------- -------- ----------------
 N                                                                VARCHAR2

SQL> CREATE OR REPLACE VIEW V_TEST AS
  2  SELECT '' N FROM DUAL
  3  UNION ALL
  4  SELECT NULL FROM DUAL;

视图已创建。

SQL> DESC V_TEST
 
名称                                                    是否为空? 类型
 ------------------------------------------------------- -------- ----------------
 N                                                                CHAR

两个SQL的区别只是UNION ALL两个查询的顺序,而恰恰就是这个顺序决定了最终视图中字段的类型。从这一个SQL可以得出三个推论,一、UNION ALL查询由前面的SQL作为类型的主导;二、空字符串’’的默认类型是CHAR;三、NULL的默认类型是VARCHAR2。

除了上面的结果外,TO_NUMBER(NULL)也比较有意思:

SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT TO_NUMBER(NULL) N FROM DUAL
  3  UNION ALL
  4  SELECT TO_CHAR(NULL) FROM DUAL;

视图已创建。

SQL> DESC V_TEST
 
名称                                                    是否为空? 类型
 ------------------------------------------------------- -------- ---------------------
 N                                                                VARCHAR2

SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT TO_NUMBER(NULL) N FROM DUAL
  3  UNION ALL
  4  SELECT TO_DATE(NULL) FROM DUAL;

视图已创建。

SQL> DESC V_TEST
 
名称                                                    是否为空? 类型
 ------------------------------------------------------- -------- ---------------------
 N                                                                DATE

SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT TO_CHAR(NULL) N FROM DUAL
  3  UNION ALL
  4  SELECT TO_NUMBER(NULL) FROM DUAL;
SELECT TO_CHAR(NULL) N FROM DUAL
       *
第 2 行出现错误:
ORA-01790:
表达式必须具有与对应表达式相同的数据类型


SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT TO_CHAR(NULL) N FROM DUAL
  3  UNION ALL
  4  SELECT TO_DATE(NULL) FROM DUAL;
SELECT TO_CHAR(NULL) N FROM DUAL
       *
第 2 行出现错误:
ORA-01790:
表达式必须具有与对应表达式相同的数据类型


SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT TO_DATE(NULL) N FROM DUAL
  3  UNION ALL
  4  SELECT TO_NUMBER(NULL) FROM DUAL;
SELECT TO_DATE(NULL) N FROM DUAL
       *
第 2 行出现错误:
ORA-01790:
表达式必须具有与对应表达式相同的数据类型


SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT TO_DATE(NULL) N FROM DUAL
  3  UNION ALL
  4  SELECT TO_CHAR(NULL) FROM DUAL;
SELECT TO_DATE(NULL) N FROM DUAL
       *
第 2 行出现错误:
ORA-01790:
表达式必须具有与对应表达式相同的数据类型

似乎在UNION ALL第一个查询中指定的TO_NUMBER没有起到确定NUMBER类型的作用,而如果缓冲CAST则不会出现这种情况:

SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT CAST(NULL AS NUMBER) N FROM DUAL
  3  UNION ALL
  4  SELECT TO_CHAR(NULL) FROM DUAL;
SELECT CAST(NULL AS NUMBER) N FROM DUAL
       *
第 2 行出现错误:
ORA-01790:
表达式必须具有与对应表达式相同的数据类型

但是要是TO_NUMBER一点作用都没有也不尽然:

SQL> CREATE OR REPLACE VIEW V_TEST AS 
  2  SELECT TO_NUMBER(NULL) N FROM DUAL
  3  UNION ALL
  4  SELECT NULL FROM DUAL;

视图已创建。

SQL> DESC V_TEST
 
名称                                                    是否为空? 类型
 ------------------------------------------------------- -------- -------------------
 N                                                                NUMBER

总之,NULL总会给我们带来一些意想不到东西。

 

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-670308/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11077234