使用Oracle零日期
我有一个应用程序与现有的数据,在日期列中有零。使用Oracle零日期
当我看着它从sqlplus中我看到: 00 DECEMB
当我使用转储功能上本专栏中,我得到: 典型值= 12长度= 7:100,100,0,0,1 ,1,1
我需要从.NET中现有的数据(没有更改数据,或者数据结构,甚至现有的SQL语句)
如何破解我读它的值,或工作写下来。
的数据库版本的不同而不同,从8到11
帮助,将不胜感激
在一天结束时,我的问题没有解决办法。
我所做的是,每当业务逻辑试图输入一个零日期,我将其更改为1/1/0001,并且当我有1/1/0001或db的异常时,我的行为在业务逻辑就好像我有零日期。
10k年的时间戳会发生什么? ;-) – 2011-05-31 12:51:45
恭喜你,这是一个门将!
典型值= 12长度= 7:100,100,0,0,1,1,1
在垃圾堆里的元素是世纪,年,月,日,时分秒。所以,你有没有什么midight上0-0-0000,这绝对不是一个有效的日期......
SQL> create table d (d1 date)
2/
Table created.
SQL> insert into d values (to_date('00-00-0000', 'dd-mm-yyyy'))
2/
insert into d values (to_date('00-00-0000', 'dd-mm-yyyy'))
*
ERROR at line 1:
ORA-01847: day of month must be between 1 and last day of month
SQL>
编辑
我用加里出色的技巧,撬棍零日期为表....
SQL> select * from d
2/
D1
---------
00-DECEMB
19-JAN-10
SQL>
所以至少我们知道你的“魔术”开发人员如何做到这一点。现在我们所要做的就是围绕他们的聪明。
我认为只有这样,才能做到这一点 - 你可能不会喜欢它 - 是要建立一个API层,使用视图....
SQL> create or replace view v_d as
2 select case when d1 = trash_date then null else d1 end as d1
3 from d
4/
View created.
SQL> select * from v_d
2/
D1
---------
19-JAN-10
SQL>
不是最少的令人不安的方面这是你需要有INSTEAD IF触发器,它实际上将零日期插入到基础表(再次使用Gary的函数)。此外,为了保持相同的对象名称,您可能需要在不同的架构中构建API。
因此,我并未尽量减少涉及的工作量。问题是,以前的开发人员在解决方案时遇到了很多技术债务。现在要偿还债务(因为你不想通过重写数据库来还清资本)。
末重大新闻
我刚刚遇到这个有趣的日期在我自己的环境,它提供了这些有趣的日期另一种解释。我为有行的表添加了一个DATE列。我使用DEFAULT子句将默认值设置为sysdate。猜猜发生了什么?
SQL> select * from t69
2/
ID
----------
1
2
SQL> alter table t69 add col2 date default sysdate not null
2/
Table altered.
SQL> select * from t69
2/
ID COL2
---------- ---------
1 00-DECEMB
2 00-DECEMB
SQL>
对于记录,sysdate按预期对新行进行工作...
SQL> insert into t69 (id) values (3)
2/
1 row created.
SQL> select * from t69
2/
ID COL2
---------- ---------
1 00-DECEMB
2 00-DECEMB
3 28-APR-10
SQL>
由于APC发现您不能从SQL * PLUS修复此问题。我遇到了来自jdbc更新值的类似问题。
我可以想出的唯一解决方案是更新行以将日期设置为合理的(如果仍然不正确)值 - 您需要使用主键引用行(不包括相关列)或使用rowid或对日期列在外的所有内容进行更新,使用创建不良数据的同类工具(即不是sql * plus),看起来似乎是有效范围(即不是sql * plus)
(OH - 并尝试解决造成问题的bug!)
HTH
C.
不确定你期望实现什么,但是你可以通过DBMS_STATS.CONVERT_RAW_VALUE生成'cruddy'dayes。
create or replace function stats_raw_to_date (p_in raw) return date is
v_date date;
v_char varchar2(25);
begin
dbms_stats.CONVERT_RAW_VALUE(p_in, v_date);
return v_date;
exception
when others then return null;
end;
/
select x, dump(x) y from (select stats_raw_to_date('64640000010101') x from dual);
那么,什么可以帮助是一个功能
create or replace function trash_date return date deterministic is
v_date date;
begin
dbms_stats.CONVERT_RAW_VALUE('64640000010101', v_date);
return v_date;
end;
/
然后你可以使用在查询像
select case when date_col = trash_date then null else date_col
from table...
您是否知道从.Net获取RAW值的方式 - 无需操作sql本身? – Noam 2010-01-19 07:06:33
不知道.Net 。现有的SQL返回一个日期,它是七个字节,或者它用TO_CHAR将它转换为一个字符串,如果它使用了TO_CHAR,那么你就会解释这个字符串,如果它返回一个Oracle日期,那么是否有可能选择一个日期列作为OracleBinary而不是OracleDate? – 2010-01-19 22:11:08
这是可笑的危险与Oracle如何使用优化的统计数据做。
你有一个无效的,人为的低日期值,它几乎肯定被用作NULL代理。 Oracle不知道它是一个NULL替代品,只是一个值,所以当它收集优化器统计信息时,它将使用该无效日期作为列的低值,并假定数据线性分布在高和低值被发现,并且数据总量的10%位于高值之上并且低于低值。
如果您有NULL(缺失或无效)数据,请将NULL数据写入表中。
对我而言,不幸的是,这是一个遗留数据的传统应用程序,在这个有问题的价值。 – Noam 2010-01-27 15:30:48
请澄清一些事情。这些日期已经在你的Oracle数据库中了吗?如果是这样,他们是否真的在DATE数据类型的列中保存?或者你是否试图从不同的数据库产品中导入它们。 – APC 2010-01-18 13:42:51
是的,这些日期已经在数据库中。 该列是DATE数据类型。 – Noam 2010-01-18 14:13:54
当你阅读.NET应用程序中的行时,列中出现了哪些内容? – 2010-01-18 18:10:58