Jaa*_*nna 1 oracle plsql oracle11g plsqldeveloper
有一些不寻常的事情发生.虽然移民,我有2050年之后一些时间(例如,二○五○年五月二十○日,21.11,2051),但由于某些原因,他们的Oracle更改为1950年,1951年等.如果你问我,它是由客户报告很烦人.这些是退休日期,所以很明显他们不能在20世纪50年代和60年代
原始表中的日期类似于YYYYMMDD格式,即20500130.所以这是我的合并声明
MERGE INTO employment_data emp
USING temp_02 src
ON (TO_NUMBER(src.id) = emp.id)
WHEN MATCHED THEN UPDATE SET
emp.retirement_day = DECODE(TO_NUMBER(src.retirement), 0, NULL, TO_DATE(src.retirement, 'YYYY.MM.DD'));
Run Code Online (Sandbox Code Playgroud)
其他日期还可以(例如20301204),但是2050年之后的任何日期都是疯狂的.知道我怎么能解决这个烦恼?
Thx提前:-)
问题在于DECODE力量是一种隐含的转换.DECODE函数的返回数据类型由规则确定:
Run Code Online (Sandbox Code Playgroud)DECODE(expr, search, result [, search, result]* [, default])在比较之前,Oracle会自动将
expr每个search值转换为第一个值的数据类型search.Oracle会自动将返回值转换为与第一个相同的数据类型result.如果第一个result具有数据类型CHAR或第一个result为null,则Oracle将返回值转换为数据类型VARCHAR2.
在Oracle中NULL具有默认数据类型,VARCHAR2因此您的DECODE表达式等效于:
DECODE(TO_NUMBER(src.retirement), 0,
NULL,
TO_CHAR(TO_DATE(src.retirement, 'YYYY.MM.DD')));
Run Code Online (Sandbox Code Playgroud)
如果没有格式,则TO_CHAR使用您的NLS_DATE_FORMAT会话设置,可能是DD-MON-RR失去世纪信息的默认值.
- 如果指定的两位数年份是00到49,那么
- 如果当前年份的最后两位数字是00到49,那么返回的年份与当前年份的前两位数字相同.
- 如果当前年份的最后两位数字是50到99,那么返回年份的前2位数字比当前年份的前2位数字大1.
- 如果指定的两位数年份是50到99,那么
- 如果当前年份的最后两位数字是00到49,那么返回年份的前2位数字比当前年份的前2位数字少1.
- 如果当前年份的最后两位数字是50到99,那么返回的年份与当前年份的前两位数字相同.
这就是2050年之前的日期没有引发神秘行为的原因!