2014-07-05 39 views
1

我一直在处理2005年由其他公司编写的复杂视图。我试图理解它在这篇文章之外的原因。由于这种观点的高度复杂性(超过500行代码),我认为作家们在做他们在做的事情。Oracle,需要帮助了解to_number和to_date函数

我一直在各个地方找到类似TO_NUMBER(null),TO_DATE(null)的东西。

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

+1

我的猜测是,这是用来强制一个空的列有一个特定的数据类型。如果我没有弄错,只使用'null'并不能保证类型 –

+1

这就像一个人每隔几秒钟拍手以避开大象。当你指出没有大象时,他只会说:“看,它行得通!”该代码解决了首先不存在的问题。这是迷信。 –

回答

0

作为一名oracle PL/SQL程序员,我确实没有找到任何合乎逻辑的理由来完成您指定的工作。在oracle中处理null的唯一合理方法是使用nvl(),我真的没有找到任何理由在复杂的视图中使用TO_NUMBER(null),TO_DATE(null)

1

显式铸造NULL可能会从8i中遗留下来,或者解决一个错误,或者像ammoQ所说的“迷信”。

在一些旧的和罕见的情况下,NULL在集合操作中的隐式转换导致诸如ORA-01790: expression must have same datatype as corresponding expression之类的错误。 我找不到这个旧的行为任何伟大的引用,但谷歌返回声称像这样的查询将在8i中失败的几个结果:

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

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

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

+0

我想你可能会走在正确的轨道上。你的联合例子显示了它是如何使用的。我也同意你的代码大小和编程技能之间的负相关性。花了整整一天的时间对这个怪物进行逆向工程后,我不得不说,如果它被分解成更小的更易处理的香料,它会更有效率。 –

2

默认为空没有一个数据类型:

SQL> select dump(null) from dual; 

DUMP 
---- 
NULL 

SQL> 

然而,如果我们迫使甲骨文做出决定,则默认为使其成为一个字符串:

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的数据库,即使我使用首先声明查询空(这通常开车的事情)我仍然得到正确的数据类型:

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

嗯,我宁愿CAST(NULL AS DATE)CAST(NULL AS NUMBER)代替TO_DATA(NULL),看起来更在我眼中合乎逻辑。

我知道需要这种表达的两种情况。 UNION的情况就是这样,正如其他唱片中已经说过的那样。

另一种情况是重载过程/函数的情况下,例如:调用像MY_PROC(NULL);程序不起作用,Oracle不知道要执行哪个程序

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(CAST(NULL AS DATE));