如何在Oracle中将年份格式“yy”转换为“yyyy”

时间:2014-12-12 07:50:53

标签: sql oracle

我尝试将表G0DM中的值插入到G0RDM中。我们面临的问题是表格GODM中的列DOJS中的日期某些日期被指定为" 01-01-00"格式..年份值输入为" 00"需要显示为2000.我尝试手动更改数据库条目,但即使我尝试了错误继续。与日期相关的其他列也存在相同的问题。所以手动更改它是如此困难..

我的查询:

INSERT INTO g0rdm
            (aud_number,
             short_code,
             entitlement_number,
             abbrevi,
             name,
             designation,
             person_charge,
             office_name,
             place,
             dob,
             dojs)
SELECT aud_number,
       short_code,
       entitlement_number,
       abbrevi,
       name,
       designation,
       person_charge,
       office_name,
       place,
       To_date(dob, 'dd-mm-yyyy'),
       To_date(dojs, 'dd-mm-yyyy')
FROM   g0dm; 

错误消息是:

SQL Error: ORA-01841: (full) year must be between -4713 and +9999, and not be 0
01841. 00000 -  "(full) year must be between -4713 and +9999, and not be 0"
*Cause:    Illegal year entered
*Action:   Input year in the specified range

任何解决方案?

1 个答案:

答案 0 :(得分:3)

好的,我们现在有更多信息 - 这是一个完整的重写答案。

我们有一个源表:

create table g0dm (
   aud_number  number
 , dob         VARCHAR2(20)
);

源表格是从CSV文件中填充的,出生日期写得很糟糕,有时一年有两位数字,有时一年有4位数字。因此,此表中的数据类型为VARCHAR2。

以下是一些模拟CSV文件导入的示例数据插页:

insert into g0dm values (1 , '01-01-1900');
insert into g0dm values (2 , '01-02-1949');
insert into g0dm values (3 , '01/03.1950');
insert into g0dm values (4 , '01-04-2000');
insert into g0dm values (5 , '01.05.00');
insert into g0dm values (6 , '01-06-49');
insert into g0dm values (7 , '01-07-50');
insert into g0dm values (8 , '1/8-2015');
insert into g0dm values (9 , '01.SEP.2016');
insert into g0dm values (10, '01/10. 2017');
insert into g0dm values (11, '1-NOV   2018');
insert into g0dm values (12, '01  DEC  2019');
commit;

然后我们有目标表:

create table g0rdm (
   aud_number  number
 , dob         DATE
);

在目标表中,我们希望将出生日期作为真正的DATE,以便我们可以在应用程序中正确使用它。 (作为DATE列,具有任何格式 - 它始终包含世纪,年,月,日,小时,分钟和秒。)

要将数据从源复制到目标并将dob从VARCHAR2转换为DATE,我们可以使用使用TO_DATE的INSERT语句:

insert into g0rdm (aud_number, dob)
select aud_number
     , to_date(dob, 'DD-MM-RRRR')
  from g0dm;

commit;

通过使用年份的RRRR格式而不是YY,YYYY或RR,可以处理源数据中的2位数和4位数年份。我们可以通过选择插入到目标表g0rdm中的内容来查看结果:

select aud_number
     , to_char(dob, 'DD. Mon YYYY') dob_as_string
  from g0rdm
 order by aud_number;

AUD_NUMBER DOB_AS_STRIN
---------- ------------
         1 01. Jan 1900
         2 01. Feb 1949
         3 01. Mar 1950
         4 01. Apr 2000
         5 01. May 2000
         6 01. Jun 2049
         7 01. Jul 1950
         8 01. Aug 2015
         9 01. Sep 2016
        10 01. Oct 2017
        11 01. Nov 2018
        12 01. Dec 2019

12 rows selected.

请参阅aud_number 5,6和7,了解RRRR如何处理2位数年份。

该文档说明了日期/时间格式模型:http://docs.oracle.com/database/121/SQLRF/sql_elements004.htm#i34924

特别是它解释了两位数年份的RR(以及RRRR)处理:http://docs.oracle.com/database/121/SQLRF/sql_elements004.htm#i116004

(作为旁注 - 您可以跳过两个表,然后直接将CSV导入到具有DATE列的目标表中。这取决于您实际执行导入的方式,导入工具是否接受指定日期格式为DD-MM-RRRR。如果你使用外部表或sql加载器,你可以这样做。否则上面的解决方案可以工作。)