为 2000 年之前的时期插入只有 YY 格式的生日 Oracle DB
Insert Birthdate with only YY format for period before 2000 Oracle DB
我有一个文件,我可以在其中接收生日并将它们插入到我的数据库中。
格式如下
03-JUN-52
我使用以下脚本插入日期
update data."PersonBDates" set BIRTHDATE = to_date('13-SEP-47', 'DD-MON-YY');
我也用过
update data."PersonBDates" set BIRTHDATE = to_date('13-SEP-47', 'DD-MON-RR');
但是当我检查是否找到它时是 2074 而不是 1947。
如何将这个日期插入到我的 oracle 数据库中?
一般来说,RR
应该有效,但 - 并非在所有情况下。您必须先修复数据,因为 RR
将 return 不同的值:
- 从
00
到 49
的年份,您将在本世纪 、20xx
,而
50
到99
将return上个世纪,19xx
这是一个例子:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> select
2 to_date('03-07-52', 'dd-mm-rr') rr1,
3 to_date('03-07-52', 'dd-mm-yy') yy1 ,
4 --
5 to_date('03-07-47', 'dd-mm-rr') rr2,
6 to_date('03-07-47', 'dd-mm-yy') yy2
7 from dual;
RR1 YY1 RR2 YY2
---------- ---------- ---------- ----------
03.07.1952 03.07.2052 03.07.2047 03.07.2047
SQL>
如您所见,RR
和 YY
年份 47
return 2047
.
的格式掩码
怎么办?将 19
连接到所有年份,例如
SQL> with test (col) as
2 (select '03-07-52' from dual union all
3 select '03-07-47' from dual
4 )
5 select col,
6 to_date(substr(col, 1, 6) || '19' || substr(col, -2), 'dd-mm-rrrr') result
7 ---------------- ---------------
8 -- this is "03-07-" "19" the last 2 digits
9 --
10 from test;
COL RESULT
-------- ----------
03-07-52 03.07.1952
03-07-47 03.07.1947
SQL>
[编辑]
如果您当前的插入脚本工作正常 - 我怀疑,关于您在评论中提到的错误代码:
ORA-01858: a non-numeric character was found where a numeric was expected
这意味着并非所有输入数据都具有相同的、预期的和正确的 DD-MON-YY
格式,那么修复生日的简单方法可能是这样的:
从所有年份大于 2000 的日期中减去 100 年
方法如下:
SQL> create table test (birthdate date);
Table created.
SQL> insert into test
2 select to_date('03-07-52', 'dd-mm-rr') from dual union all
3 select to_date('03-07-47', 'dd-mm-rr') from dual;
2 rows created.
SQL> select * from test;
BIRTHDATE
----------
03.07.1952
03.07.2047
SQL> update test set
2 birthdate = add_months(birthdate, -100 * 12)
3 where extract (year from birthdate) > 2000;
1 row updated.
SQL> select * from test;
BIRTHDATE
----------
03.07.1952
03.07.1947
SQL>
当然可以修改,如果有人真的是2000年以后出生的。
关于您遇到的错误 (ORA-01858),好吧,修复它取决于您将这些值输入 table.
的准确程度
- 如果它是 SQL*Loader,无效值将被拒绝并存储到
.bad
文件中,您可以修复它们并稍后重新处理它们
- 如果它使用外部 tables,您可以使用
where
子句并忽略无效行;例如,使用 regexp_like
或者,您最好的选择是确保所有 输入值都是有效日期。然后您选择的任何选项(我之前提到过)都可以正常工作而不会出现 ORA-xxxxx 错误。
按照 Littlefoot 的建议,将 19 连接到所有年份的替代方法。
to_date(regexp_replace('13-SEP-47', '([0-9]+$)', '19'), 'DD-MON-YYYY')
我建议实施 01
不被视为 1901
而是 2001
或类似的解决方案(我假设生日年份不是 1901
您系统中的任何人)。
Case when substr(col, -2) < to_char(sysdate,'YY')
then to_date(col, 'DD-MON-YY')
else to_date(substr(col, 1, 6) || '19' || substr(col, -2), 'dd-mm-rrrr'
End
干杯!!
我有一个文件,我可以在其中接收生日并将它们插入到我的数据库中。
格式如下
03-JUN-52
我使用以下脚本插入日期
update data."PersonBDates" set BIRTHDATE = to_date('13-SEP-47', 'DD-MON-YY');
我也用过
update data."PersonBDates" set BIRTHDATE = to_date('13-SEP-47', 'DD-MON-RR');
但是当我检查是否找到它时是 2074 而不是 1947。 如何将这个日期插入到我的 oracle 数据库中?
一般来说,RR
应该有效,但 - 并非在所有情况下。您必须先修复数据,因为 RR
将 return 不同的值:
- 从
00
到49
的年份,您将在本世纪 、20xx
,而 50
到99
将return上个世纪,19xx
这是一个例子:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> select
2 to_date('03-07-52', 'dd-mm-rr') rr1,
3 to_date('03-07-52', 'dd-mm-yy') yy1 ,
4 --
5 to_date('03-07-47', 'dd-mm-rr') rr2,
6 to_date('03-07-47', 'dd-mm-yy') yy2
7 from dual;
RR1 YY1 RR2 YY2
---------- ---------- ---------- ----------
03.07.1952 03.07.2052 03.07.2047 03.07.2047
SQL>
如您所见,RR
和 YY
年份 47
return 2047
.
怎么办?将 19
连接到所有年份,例如
SQL> with test (col) as
2 (select '03-07-52' from dual union all
3 select '03-07-47' from dual
4 )
5 select col,
6 to_date(substr(col, 1, 6) || '19' || substr(col, -2), 'dd-mm-rrrr') result
7 ---------------- ---------------
8 -- this is "03-07-" "19" the last 2 digits
9 --
10 from test;
COL RESULT
-------- ----------
03-07-52 03.07.1952
03-07-47 03.07.1947
SQL>
[编辑]
如果您当前的插入脚本工作正常 - 我怀疑,关于您在评论中提到的错误代码:
ORA-01858: a non-numeric character was found where a numeric was expected
这意味着并非所有输入数据都具有相同的、预期的和正确的 DD-MON-YY
格式,那么修复生日的简单方法可能是这样的:
从所有年份大于 2000 的日期中减去 100 年
方法如下:
SQL> create table test (birthdate date);
Table created.
SQL> insert into test
2 select to_date('03-07-52', 'dd-mm-rr') from dual union all
3 select to_date('03-07-47', 'dd-mm-rr') from dual;
2 rows created.
SQL> select * from test;
BIRTHDATE
----------
03.07.1952
03.07.2047
SQL> update test set
2 birthdate = add_months(birthdate, -100 * 12)
3 where extract (year from birthdate) > 2000;
1 row updated.
SQL> select * from test;
BIRTHDATE
----------
03.07.1952
03.07.1947
SQL>
当然可以修改,如果有人真的是2000年以后出生的。
关于您遇到的错误 (ORA-01858),好吧,修复它取决于您将这些值输入 table.
的准确程度- 如果它是 SQL*Loader,无效值将被拒绝并存储到
.bad
文件中,您可以修复它们并稍后重新处理它们 - 如果它使用外部 tables,您可以使用
where
子句并忽略无效行;例如,使用regexp_like
或者,您最好的选择是确保所有 输入值都是有效日期。然后您选择的任何选项(我之前提到过)都可以正常工作而不会出现 ORA-xxxxx 错误。
按照 Littlefoot 的建议,将 19 连接到所有年份的替代方法。
to_date(regexp_replace('13-SEP-47', '([0-9]+$)', '19'), 'DD-MON-YYYY')
我建议实施 01
不被视为 1901
而是 2001
或类似的解决方案(我假设生日年份不是 1901
您系统中的任何人)。
Case when substr(col, -2) < to_char(sysdate,'YY')
then to_date(col, 'DD-MON-YY')
else to_date(substr(col, 1, 6) || '19' || substr(col, -2), 'dd-mm-rrrr'
End
干杯!!