Oracle需要帮助理解to_number和to_date函数

时间:2014-07-05 13:55:28

标签: oracle

我一直在处理其他公司在2005年撰写的复杂观点。我试图了解它正在做什么,超出了这篇文章的原因。由于这种观点的高度复杂性(超过500行代码),我认为作者们新的是他们在做什么。

我会在不同的地方发现TO_NUMBER(null),TO_DATE(null)等内容。

对我而言似乎完全不必要地使用了一个功能。 是否有任何技术原因或优势证明为什么这样设计是这样的?

4 个答案:

答案 0 :(得分:2)

默认情况下,NULL没有数据类型:

SQL> select dump(null) from dual;

DUMP
----
NULL

SQL>

但是,如果我们强制Oracle做出决定,它将默认为使其成为字符串:

SQL> create or replace view v1 as
select 1 as id
       , null as dt
from dual
/
  2    3    4    5  
View created.

SQL> desc v1
 Name           Null?    Type
 -------------- -------- ----------------------------
 ID                      NUMBER
 DT                      VARCHAR2

SQL>

但这并不总是令人满意的。我们可能需要在视图中使用NULL,原因有很多(定义API,填充锯齿状的UNION等),因此我们将NULL转换为另一种数据类型以获得我们需要的投影。

SQL> create or replace view v1 as
select 1 as id
       , to_date(null) as dt
from dual
/
  2    3    4    5  
View created.

SQL> desc v1
 Name           Null?    Type
 -------------- -------- ----------------------------
 ID                      NUMBER
 DT                      DATE

SQL> 

后来的版本在处理UNION方面变得更加智能。在我的11gR2数据库中,即使我在第一个声明的查询中使用null(并且通常驱动的东西),我仍然得到正确的数据类型:

SQL> create or replace view v1 as
select 1 as id
       , null as dt
from dual
union all
select 2 as id
       , sysdate as something_else
from dual
/
  2    3    4    5    6    7    8    9  
View created.

SQL> 
SQL> desc v1
 Name           Null?    Type
 -------------- -------- ----------------------------
 ID                      NUMBER
 DT                      DATE

SQL> 

答案 1 :(得分:1)

显式转换NULL可能会从8i中遗留下来,或者解决错误,或者像ammoQ所说,"迷信"。

在一些罕见的情况下,集合操作中NULL的隐式转换会导致ORA-01790: expression must have same datatype as corresponding expression之类的错误。   我找不到任何有关此旧行为的好参考资料,但Google会返回一些结果,声称这样的查询会在8i中失败:

select 'a' a from dual
union
select null a from dual;

至少有一个类似的错误,"错误9456979错误的结果是将NVL / DECODE推入UNION视图并使用NULL选择列表项 - 取代"。

但不要让16岁的软件和一些罕见的bug决定如何编程。并且不要认为代码大小编程技能之间存在正相关关系。这是一个负面的相关性:优秀的程序员将创建更小,更易读的代码,并且不会为未来的编码人员留下许多谜团。

答案 2 :(得分:1)

好吧,我希望CAST(NULL AS DATE)CAST(NULL AS NUMBER)代替TO_DATA(NULL),在我看来更合乎逻辑。

我知道需要这种表达式的两种情况。 其中一个就是UNION的情况,正如其他aswers所述。

另一种情况是程序/功能过载的情况,例如:

CREATE OR REPLACE PROCEDURE MY_PROC(val IN DATE) AS
BEGIN
   DELETE FROM EMP WHERE HIRE_DATE = val;
END;
/

CREATE OR REPLACE PROCEDURE MY_PROC(val IN NUMBER) AS
BEGIN
   DELETE FROM EMP WHERE EMP_ID = val;
END;
/

调用类似MY_PROC(NULL);的过程不起作用,Oracle不知道要执行哪个过程。您必须将其称为MY_PROC(CAST(NULL AS DATE));,例如。

答案 3 :(得分:0)

作为一名oracle PL / SQL程序员,我真的没有找到任何合理的理由去做你指定的事情。在oracle中处理null的唯一合理方法是使用nvl(),我真的没有找到在复杂视图中使用TO_NUMBER(null)TO_DATE(null)的任何理由