我有一个临时表,其中包含日期为字符串,格式为' mm / dd / yy'。在加载到主表之前,我有Oracle 11g过程将字符串转换为日期格式。我使用to_date('03/20/34','mm/dd/rr')
转换为日期格式,错误输出为03/20/2034,而正确的日期是03/20/1934。请帮助我获取正确的输出,其中我的表包含几个世纪的日期。
答案 0 :(得分:1)
“我正在使用to_date('03 / 20/34','mm / dd / rr')转换为日期格式,它提供错误的输出为03/20/2034,而正确的日期是03/20 / 1934年。“
RR
是甲骨文在上一个千年中引入的黑客行为,是解决the Y2K bug的斗争的一部分。标准日期掩码YY
将世纪默认为当前世纪。但在1999年,01/01/00
更可能意味着01/01/2000
而不是01/01/1900
。所以RR
hack是使用在00
上旋转的固定窗口来推导日期世纪:值00-49给出世纪20
,给出50-99 19
。显然,有些时候这种猜测是错误的,但引入的数据损坏程度低于将所有日期默认为世纪19
。
关键是,窗户是固定的。它本来是一个临时解决方案,因为没有时间将所有遗留系统切换到2000年到来之前使用四位数年份。但愿景始终是所有系统都将在长期内得到修复,即使只是通过退休或更换。当然没有人预计会建造支持两位数年份的新系统。
现在 2017 ,并且没有理由让系统仍然使用两位数年份。在过去的日子里,存储空间很昂贵,从日期开始刮两位数就可以节省宝贵的空间。现在只是邋。了。
这显然无法帮助您解决问题。简短的回答是无法更改RR
使用的支点。最好的解决方案是对系统的数据输入方面实施更严格的验证,并坚持四位数年。这是否可行取决于你的办公室政治。另一种解决方案是编写自己的转换函数:
create or replace function my_to_date (p_str varchar2) return date as
begin
if to_number(substr(p_str, 7) <= 35 then
return to_date(substr(p_str, 1, 6)||'19'||substr(p_str, 7), 'dd/mm/yyyy');
else
return to_date(substr(p_str, 1, 6)||'20'||substr(p_str, 7), 'dd/mm/yyyy');
end;
显然,您需要定义用于决定是使用19
还是20
的实际规则。
答案 1 :(得分:0)
在插入90年代后期的日期值时,我也遇到了类似的问题。脚本中的格式为DD-MON-YY,因此数据库将其读取为20YY,而不是19YY。
我非常优雅的解决方案是打开原始数据文件,并在YY年值之前添加一个“ 19”。